I have an unordered list of elements organized in rows. When a user clicks on a row, I want the text in the row to be appended into a separate text field. The issue with my current code is that I if the user clicks multiple boxes, all of the associated text with each of those boxes will be appended into the textfield. I would like to append the text from only the last row element that the user clicked.
Here is my javascript:
function clickEvents() {
// Day List Selector
$('#DC_id_1').click(function() {
$('#whenTextField').attr('value', 'Today');
});
$('#DC_id_3').click(function() {
$('#whenTextField').attr('value', 'Tomorrow');
});
$('#DC_id_5').click(function() {
$('#whenTextField').attr('value', 'Later');
});
// Time List Selector
$('#DC_id_37').click(function() {
var day = $('#whenTextField').attr('value');
$('#whenTextField').attr('value', day + ', Right Now');
});
$('#DC_id_39').click(function() {
var day = $('#whenTextField').attr('value');
$('#whenTextField').attr('value', day + ', Morning');
});
$('#DC_id_41').click(function() {
var day = $('#whenTextField').attr('value');
$('#whenTextField').attr('value', day + ', Midday');
});
$('#DC_id_43').click(function() {
var day = $('#whenTextField').attr('value');
$('#whenTextField').attr('value', day + ', Afternoon');
});
$('#DC_id_45').click(function() {
var day = $('#whenTextField').attr('value');
$('#whenTextField').attr('value', day + ', Evening');
});
}
Basically, I think I want to use an "if" statement to control the clicking in the Time List Selector elements list.
example:
if (DC_id_37 is clicked) { append('text'); } else if (DC_id_39 is clicked) { append('some other text');
Here is the associated HTML:
<ul id="dayList">
<li id="DC_id_1">
Today
</li>
<li id="DC_id_3">
Tomorrow
</li>
<li id="DC_id_5">
Later
</li>
</ul>
<ul id="timeList">
<li id="DC_id_37">
Right Now
</li>
<li id="DC_id_39">
Morning
</li>
<li id="DC_id_41">
Midday
</li>
<li id="DC_id_43">
Afternoon
</li>
<li id="DC_id_45">
Evening
</li>
</ul>
<textField id="whenTextField">
*Note I just created this HTML by hand, as I'm building the web app in Dashcode, and its putting out some very ugly HTML
Actual HTML created by Dashcode:
<ul id="timeList">
<li>
<div id="foo"></div>
<div id="DC_id_37">Right Now</div>
<div></div>
</li>
<li>
<div id="foo2"></div>
<div id="DC_id_39"></div>
<div></div>
</li开发者_开发技巧>
</ul>
Instead of simply appending the new value, you need to replace the old value. I would do it this way:
// Based on the HTML you posted, we only need two click functions.
$("#dayList > li > div:eq(1)").click(function() {
var newDate = $(this).text();
var currentValues = $("#whenTextField").attr("value").split(", ");
// Initialize this as an empty string in case the user has not yet selected
// a time.
var time = "";
// Get the previous time, if one has already been appended.
if (currentValues.length == 2) {
time = ", " + currentValues[1];
}
// Update the value of the text field.
$("#whenTextField").attr("value", newDate + time);
});
$("#timeList > li > div:eq(1)").click(function() {
// Get the current date value.
var date= $("#whenTextField").attr("value").split(", ")[0];
// Get the text from the 'li' element that raised the event.
var time = $(this).text();
// Update the value of the text field, keeping the previously selected date.
$("#whenTextField").attr("value", date + ", " + time);
});
This approach also saves the selected time if a user later changes the selected date.
Update:
I updated my example to match the second nested <div />
element under each <li />
using the :eq(n) selector (the selector is zero-based). This solution assumes that the target <div />
elements will always be the second one, based on your comment.
You have a few other options, too:
You could use the :parent selector to affect only
<divs />
that contain text (or any child elements).$("#timeList > li > div:parent").click(function() { });
Or, you could use the Attribute Starts With Selector to affect only
<div />
elements with IDs that start with "DC_id_".$("#timeList > li > div[id^='DC_id_']").click(function() { });
I'm not sure which solution performs the best. Personally, I would recommend going with the third option (the Attribute Starts With selector) since generated IDs are usually more predictable than an element's index or contents.
I believe this is what you're looking for:
$('#DC_id_37').click(function() {
var day = $('#whenTextField').attr('value').split(",")[0];
$('#whenTextField').attr('value', day + ', Right Now');
});
The .split(",")[0]
will grab the first part of what's in the text box.
You could simplify your code with something like this:
$('#dayList li').click(function() {
$('#whenTextField').attr('value',$(this).text());
});
$("#timeList li").click(function() {
var day = $('#whenTextField').attr('value').split(",")[0];
$('#whenTextField').attr('value', day + ', '+$(this).text());
});
Roughly
html: (adjust to taste, prolly have to do some css)
<div class="appointment">
<div class="options">
<ul class="day">
<li>Today</li>
<li>Tomorrow</li>
<li>Later</li>
</ul>
<ul class="time">
<li>Right Now</li>
<li>Morning</li>
<li>Midday</li>
<li>Afternoon</li>
<li>Evening</li>
</ul>
</div>
<input class="when" type="text" />
</div>
jquery
$('.appointment').each(function(){
var self = $(this)
, whenField = self.find('.when')
, day = 'choose a day'
, time = 'choose a time';
self.delegate('.options li', 'click', function(e){
var li = $(this), ul = li.closest('ul');
if(ul.hasClass('day')) {
day = li.text();
} else if(ul.hasClass('time')) {
time = li.text();
}
whenField.val(day + ' - ' + time);
});
});
Reusable on a page, so you can have more appointment boxes on a page. I personally avoid using element ID's like the plague, better abstract it and shorten code substantially if you generalize.
精彩评论