Clicking on name in <ul> creates more <li> underneath names - javascript

I have a problem getting my little script to work correctly, and was just looking for a little guidance. I'm trying to make it so that when I click on a legislator's name, it will display more information about them, underneath their name. Such as their party, and district. However, when I click on a name, all it does is post more List-items underneath the legislators names. I'm very new to programming and I'm sort of stuck on what to do here. Any suggestions? I'm using Sunlight Congress API if that helps.
Here's the HTML
<body>
<h1>Find your local legislators</h1>
<form id="get-zip">
<label for="zip">Enter your Zip code:</label>
<input id="zip" type="text">
<button type="submit">Look up</button>
</form>
<ul id="legislators"></ul>
</body>
And the JavaScript
$(function(){
$("form#get-zip").submit(function(){
var zip = $("input#zip").val();
$.get("http://congress.api.sunlightfoundation.com/legislators/locate?apikey=PUT-YOUR-API-KEY-HERE&zip=" + zip)
.done(function(responseJSON){
responseJSON.results.forEach(function(legislator){
$("ul#legislators").append("<li>" + legislator.first_name + " " + legislator.last_name + " (" + legislator.chamber + ")</li>");
$("ul#legislators").click(function(){
$("ul#legislators").append("<li>" + legislator.party + " " + legislator.district + "</li>").toggle();
});
});
});
return false;
});
});

I suggest that when you create the li elements in your forEach loop you add all of each legislator's details, but put the part for which you want to toggle visibility in a separate child element. So the dynamically created li elements would look something like this:
<li>
<p>Juanita Johansson (Senate)</p>
<p class='details'>JavaScript Party Canberra</p>
</li>
And then add a details class to your stylesheet to hide the secondary details by default:
.details { display : none; }
Note that then the visibility is not the only thing you can then style separately for the details - you could also put them in a smaller font or whatever.
Then you can add a delegated click handler to the ul element that toggles based on that class:
$(function(){
$("#legislators").on("click", "li", function(){
$(this).find("p.details").toggle();
});
$("#get-zip").submit(function(){
var zip = $("#zip").val();
$.get("http://congress.api.sunlightfoundation.com/legislators/locate?apikey=PUT-YOUR-API-KEY-HERE&zip=" + zip)
.done(function(responseJSON){
responseJSON.results.forEach(function(legislator){
$("#legislators").append(
"<li><p>" + legislator.first_name + " " + legislator.last_name +
" (" + legislator.chamber +
")</p><p class='details'>" +legislator.party + " " +
legislator.district + "</p></li>"
);
});
});
return false;
});
});
A general note about the selectors you're using: if selecting by id you can just say $("#idHere"), there's no need to include the tagname first.

Related

Can't get the ID of a button

I'm trying to get the ID of a button but I can't seem to get it but rather getting the ID of the div which isn't what I want.
Here's what I'm currently doing:
HTML
<div class="container container-about container-login">
<div id="white-container" class="white-container about-text2 bottom-padding-fortypx">
<p id="availableTitle" class="text-center avail-title">Available</p>
<p id="acceptedTitle" class="text-center accept-title">Accepted</p>
<div id="availableJ" class="contractor-dash-div available-j"></div>
<div id="acceptedJ" class="contractor-dash-div accepted-j"></div>
<div class="clear"></div>
</div>
</div>
Javascript:
i++;
$('<div>', {
id: 'available' + i,
class: "avail-accept-jobs-div margin-bottom-twentypx"
}).appendTo('#availableJ');
$('#available' + i).append('<div class="delete-job initial-hidden"><p class="text-center font-weight-bold"><b>X</b></p></div>');
// Populating the available list
$('#available' + i).append('<p class="customer-name partial-name">Name: ' + partialName + '</p>');
$('#available' + i).append('<p class="customer-name full-name initial-hidden">Name: ' + name + '</p>');
$('#available' + i).append('<p>Date: ' + date + '</p>');
$('#available' + i).append('<p>Time: ' + time + '</p>');
// Get this buttons ID
var but = $('#available' + i).append('<div class="accept-job-button text-center"><p>Accept</p></div>');
but.id = keys;
// I understand this is getting the id of the div but the button is essentially a div
$("div").click(function() {
alert(this.id);
});
My question:
How am I able to get the actual ID of the button which is actually a div?
this should be the element that fired the event.
you could also respond to the button's click event, directly, instead of waiting for it to bubble up to the div.
if you want the button ID, you can add it as an attribute to the divs firing the event.
if you add matching "btnID" data attributes to the divs and their button, you can get back what you need (in the same attribute) when the user clicks on the div or its button.
BTW, is the value of keys being updated somewhere? if not, it appears you will allow "shared" ID values.
I misread the original question. If you want to select a child element it is as follows.
$("div > .accept-job-button").click(function() {
alert(this.id);
});

implementing html tags of js variable

When I click open first window link a popup opens.
in that popup you will see a grid with two columns.
in that first column i need to combine name and and icon.
so i added span tag before a tag but its not working.
can you guys tell me how to combine.
providing code below.
http://jsfiddle.net/cepzsokp/
var a = $('<span></span><a/>', {
class: 'sportsDataPlayer',
download: 'download.csv',
type: 'text/csv',
href: URL.createObjectURL(data),
html: ev.FileName
});
return a[0].outerHTML;
You can not do that html mark up. easiest thing would be just add the span before the outerHTML
var a = $('<a></a>', {...})
return "<span></span>" + a[0].outerHTML;
I have edited your latest jsfiddle. Here is the working DEMO
I have modified this line of code as below:
return "<span onclick="window.open('" + model.mobileVersion + "', 'popup', 'width=800,height=600,scrollbars=yes,resizable=no')" class='" + skyCloudmageProfilePic + " displayInlineBlock " + kendotxtMenu + "'></span>" + a[0].outerHTML;

Activating a function when pageshow jquery mobile

I have a function within a jquery pageshow function and only should be activated when on a certain page (id). But for some reason it doesn't run that script. The pages are dynamic with id's.
Here is a sample of my code
$(document).on('pageshow', '#fragment-1', function() {
$.mobile.activePage.find("div [data-role=tabs] ul li:first-child a").click();
createCheckboxes('#fragment-2')
});
function createCheckboxes(into){
var players_names = playerCal("ars", 7, 5);
$("#createBtn").remove();
$(into).append('<fieldset class="cbFieldSet" data-role="controlgroup">');
var length = players_names[0].length;
$(".cbFieldSet").append("<ul data-role='listview' data-inset='true' data-theme='d' data-divider-theme='e' data-count-theme='b'><li data-role='list-divider'><span>Select players in the next line up2</span></li></li>");
for(var i=0;i<length;i++){
$(".cbFieldSet").append('<li><input type="checkbox" name="cb-'+i+'" id="cb-'+i+'" value="'+players_names[0][i]+'"/><label for="cb-'+i+'">'+players_names[0][i]+'</label></li>');
}
$(".cbFieldSet").append("</ul>");
$(into).trigger("create");
$("#showBtn").css("visibility","visible");
console.log(players_names);
}
Sample of my dynamic page, it works
+"<div id='fragment-1'>"
+ "<form>"
+ "<fieldset data-role='controlgroup' class = 'content'>"
+ "</fieldset>"
+ "</form>"
+ "</div>"
+ "<div id='fragment-2'>"
+ "<form>"
+ "<fieldset data-role='controlgroup' class = 'content'>"
+ "</fieldset>"
+ "</form>"
+ "</div></div></div>");
I like when someone creates clean and readable question.
You have an error in your code, div holding your page is not propperly formed jQUery Mobile page.
Change this:
<div id='fragment-1'>
To this:
<div id='fragment-1' data-role="page">
Page events works only on div containers with attribute data-role="page".
Update:
Working example made from your/my previous example: http://jsfiddle.net/Gajotres/vds2U/55/

clearing input text area with dynamic input id's on button click - jQuery

Although the question title gives an impression that I want to ask one question, but there are two problems I have facing at the moment.
I have gone through few similar questions on how to clear the input text area on button click, but most of them are for fixed input class or id's.
Problem 1: I am generating rows dynamically and and all the fields are being populated using JS thus the input ID's for all text boxes are different. Now if a user enter some number on "Apply to all" input field and click the button the same number should be set to all the rows which are added in the betslip.
Problem 2: After entering individual values in the betslip input boxes and if I click "clear all" button. It should clear all the inputs entered earlier in the bet slip.
Here is the HTML structure
<div id="bets">
<div id="idNo1" class="bet gray2" name="singleBet">
<div class="left">
<p class="title">
<p class="supermid">
<input id="input_1" type="text">
</div>
</div>
<div id="idNo2" class="bet gray2" name="singleBet">
<div class="left">
<p class="title">
<p class="supermid">
<input id="input_2" type="text">
</div>
</div>
<div id="idNo3" class="bet gray2" name="singleBet">
<div class="left">
<p class="title">
<p class="supermid">
<input id="input_3" type="text">
</div>
</div>
</div>
JS for adding element in the individual bets
function createSingleBetDiv(betInfo) {
var id = betInfo.betType + '_' + betInfo.productId + '_' + betInfo.mpid,
div = createDiv(id + '_div', 'singleBet', 'bet gray2'),
a = createA(null, null, null, 'right orange'),
leftDiv = createDiv(null, null, 'left'),
closeDiv = createDiv(null, null, 'icon_shut_bet'),
singleBetNumber = ++document.getElementsByName('singleBet').length;
// Info abt the bet
$(leftDiv).append('<p class="title"><b><span class="bet_no">' + singleBetNumber + '</span>. ' + betInfo['horseName'] + '</b></p>');
var raceInfo = "";
$("#raceInfo").contents().filter(function () {
if (this.nodeType === 3) raceInfo = $(this).text() + ', ' + betInfo['betTypeName'] + ' (' + betInfo['value'].toFixed(2) + ')';
});
$(leftDiv).append('<p class="title">' + raceInfo + '</p>');
// Closing btn
(function(id) {
a.onclick=function() {
removeSingleBet(id + '_div');
};
})(id);
$(a).append(closeDiv);
// Creating input field - This is where I am creating the input fields
$(leftDiv).append('<p class="supermid"><input id="' + id + '_input\" type="text" class="betInput"></p>');
// Creating WIN / PLACE checkbox selection
$(leftDiv).append('<p><input id="' + id + '_checkbox\" type="checkbox"><b>' + winPlace + '</b></p>');
// Append left part
$(div).append(leftDiv);
// Append right part
$(div).append(a);
// Appending div with data
$.data(div, 'mapForBet', betInfo);
return div;
}
HTML for Apply to all and Clear all button
APPLY TO ALL <input type="text">
CLEAR ALL
JS where I need to implement those 2 functions
function applyToAllBetInput() {
$('.apply').change(function() {
$(this).prevAll().find('input[type=text]').val($(this).val());
});
}
function clearAllBetInput() {
$('.clearall').click(function() {
$('div.bet').find('input').val('');
});
}
The best thing to do is remove the inline event handlers from the links, like this...
APPLY TO ALL <input type="text">
CLEAR ALL
Then, assign the event handlers in your script...
$("a.button.apply").on("click", function(e) {
e.preventDefault();
applyToAllBetInput($(this).find("input").val());
});
$("a.button.clearall").on("click", function(e) {
e.preventDefault();
applyToAllBetInput("");
});
And this would apply the value to all inputs...
function applyToAllBetInput(value) {
$("#bets div[name=singleBet] .supermid input:text").val(value);
}
If you pass a parameter into applyToAllBetInput and then set the inputs with that then you only need the one function, as they both do the same thing, but with different values. Best to only have 1 bit of code if it's only doing 1 thing, then you only have to fix it once if things change in the future :)
Please replace the id's i've given with your actual button/textarea ids (give ID's to your elements).
$('#txtApplyToAll').change(function() {
$(this).prevAll().find('input[type=text]').val($(this).val());
});
$('#btnClearAll').click(function() {
$('#txtApplyToAll').prevAll().find('input[type=text].val('');
});
There are several general suggestions I'd make before even starting to write the code. First, Why are you using longhand JavaScript when you have jQuery available? For example:
inputId = divId.document.getElementById('input');
should be simply:
inputId = $(inputId).find('input');
(or something along those lines--I'm not sure what you're after with that.)
Next, you're using inline click handlers. Instead, use event listeners:
<a href="javascript: applyToAllBetInput()" ...
Should be
$('a#my-id').click(function() { ... }
Finally, you can target all your inputs for clearing with a selector like this:
$('div.bet').find('input').val('');

Sorting consistency of dynamically created IDs on DOM Elements

My application successfully creates elements and assigns them different (increasing) IDs.
Now my issue relies when the user deletes these elements (because they have the option to delete as well as create), the consistency of these IDs get broken therefore my application doesn't run well.
This Fiddle represents what I have so far. Just a textbox that appends its value and a few other elements inside a collapsible as many times as the user wants (For some reason my fiddle doesn't increment the alert value, but it works fine on my platform).
SCRIPT (Sorry the txt variable is too long)
$('#Add').click(function () {
if ($("#MedNameStren").val() != "") {
var value = $("#MedNameStren").val();
var noOfMeds = $('#NoOfMedicines').val();
//to check current value
alert(noOfMeds);
var text = '<div data-role="collapsible" data-collapsed="true" data-iconpos="left" data-content-theme="e">' + '<h2>' + desc + '</h2>' + '<div class="ui-grid-a">' + '<div class="ui-block-a" style="width:25%; margin-right:3%;">' + '<input id="quantity' + noOfMeds + '" class="quantity" type="text" placeholder="Quantity" />' + '</div>' + '<div class="ui-block-b" style="width:70%; margin-right:2%;"">' + '<textarea id="directions' + noOfMeds + '" class="directions" cols="40" rows="4" placeholder="Directions given by your GP." ></textarea>' + '</div>' + '</div>' + '<button key="' + vpid + '">Remove</button>' + '</div>';
$("#medListLi").append(text);
$('button').button();
$('#medListLi').find('div[data-role=collapsible]').collapsible();
$('#medListLi li').listview("refresh");
$('#medListLi').trigger("create");
document.getElementById("manuallyName").value = "";
noOfMeds++
$("#NoOfMedicines").val(noOfMeds);
}
else {
alert('Please Provide Medicine Name')
}
});
I am using a counter that neatly increments the ids of quantity and description like:
quantity0
quantity1
quantity2
..and so on, but once the following script is called...
//Deletes colapsible sets (Medicines) from the selected List
$('#medListLi').on('click', 'button', function (el) {
$(this).closest('div[data-role=collapsible]').remove();
var key = $(this).attr('key');
localStorage.removeItem(key);
var noOfMeds = $('#NoOfMedicines').val();
noOfMeds--
$("#NoOfMedicines").val(noOfMeds);
//location.reload();
});
depending on which element (collapsible) is deleted, the IDs stop being consistent. For example if the collapsible with id="quantity1" is deleted then the counter will go back to 1 (currently 2) and on the next addition the respective collapsible will get an id that's already taken, and unfortunately I don't need this to happen.
Maybe I'm making this sound more complicated that it is, but will appreciate any suggestions or ideas to solve this issue (if possible).
If more information is needed, please let me know.
Was brought to my attention that creating and deleting dynamic IDs can be done but keeping up with consistency of these IDs can be very tricky to work around it.
I've solved my own problem by simply creating a function that would keep count of the IDs from the amount of collapsibles inside my list and "renewing" the ID numbers on each Add and Delete.

Categories

Resources