Working on a twitter bootstrap wizard page and outputting selected check-box values to next tab-pane. Because there can be multiple selections (ie. :checked), I'm using map function and join(). I'm trying to wrap each output in a <li> but the first item does not get wrapped -- only every item after the 1st.
Eg.
Checkbox 1
<li>Checkbox 2</li>
<li>Checkbox 3</li>
Here is my code:
$(document).ready(function() {
$('#rootwizard').bootstrapWizard({
onNext: function(tab, navigation, index) {
if (index == 1) {
if (!$('.selection:checked').val()) {
alert('Please select a solution to try');
$('.selection').focus();
return false;
}
}
$('#showSelection').html($('.selection:checked').map(function() {
return $(this).val();
}).get().join('<li>'));
}
});
Not sure if I should be using a different method? Or... if there is a way to pre-append and force a separator "wrap" around all selections. Any insight/clarity would be appreciated.
Try doing it like this:
$('#showSelection').html('<li>' + $('.selection:checked').map(function() {
return $(this).val();
}).get().join('</li><li>') + '</li>);
This is because the separator for the join will only be added in between the elements, not before and after them so your first element will not have an opening li tag and the last will not have a closing li tag.
Related
I'm working with jquery-sortable and I'm having some difficulty modifying the list container (ul) when it's been emptied or loaded empty. For example, If you have two containers:
A collection list to drag from that always contains a few items.
A destination list which loads empty (unless it is being edited and it will contain some list items but can be emptied by dragging them out of there
The empty container (ul) should display a message (i.e. nothing here) whenever it loads empty or it gets emptied on edit.
I tried several approaches with no avail.
SAMPLE HTML FOR EMPTY CONTAINER
<ul id="mediaItemsListDest" class="playlist-items connectedSortable">
<!-- force a message in html -->
<p>Drag and drop an item from the list</p>
</ul>
DIFFERENT JQUERY APPROACHES
if( $("#mediaItemsListDest li").length >= 1 ) {
//remove it when the ul contains an li
$("#mediaItemsListDest p").css('display','none');
}
or
if( $("#mediaItemsListDest li").length === 0 ) {
//no li is found, display a message via jquery but don't add it as a <p> element in the html
$(this).html("Sorry, this is empty");
}
or
if( !$("#mediaItemsListDest").has("li").length ) {
$(this).html("Sorry, this is empty");
}
None of them worked. How else can I hijack this empty or emptied list?
Here's a testing fiddle for you:
DEMO
Thanks in advance.
You need to handle on every list change the error message state so let's say we have the following HTML - example from your demo:
<ol id="mediaItemsListDest" class="simple_with_animation vertical">
<p>Drag and drop an item from the list</p>
<li>Item 1</li>
<li>Item 2</li>
</ol>
Additionally I have extended with a function which is handling the message state, code is placed on initialization part of the application:
function handleMessage() {
let liObjects = $('#mediaItemsListDest li');
let message = $('#mediaItemsListDest p');
console.log('length', liObjects.length);
console.log('message', message);
if (liObjects.length !== 0) {
message.css('display', 'none');
} else {
message.css('display', 'inline');
}
}
handleMessage();
This function needs to be called in onDrop event:
onDrop: function ($item, container, _super) {
// code part removed but you can find in your demo
handleMessage();
}
I did a quick test and it was working fine. I hope this one is helping, let me know if you need more information.
I have an unordered list called $myList. Every time a string ($entry) is entered into an input, I want to run through the list to see if that string is already in the list. If it is, I want to remove the list item that contains the matching string. Either way, the new string gets added and becomes a new list item.
Here's the most recent thing I tried:
$myList.text().filter($entry).remove();
$myList.append($entry);
It doesn't like that I'm doing .text().filter(), but none of the other things I've tried have worked either.
What's a simple way to accomplish this?
The filter method should act on the list items, not on the text() value, since it is one of the list items you might need to remove. The filter method needs a function as argument. That function should determine whether or not the text() value of the iterated item is the entry text. Then the remove will work:
$('li', $myList).filter(function () {
return $(this).text() == entry;
}).remove();
$('button').click(function () {
var entry = $('input').val();
var $myList = $('ul');
$('li', $myList).filter(function () {
return $(this).text() == entry;
}).remove();
$('<li>').text(entry).appendTo($myList); // add item at end of list
$('input').val(''); // clear input
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input><button>Add</button>
<ul></ul>
$myList.find("li").filter(function() { // for each list item
return $(this).text() === $entry; // pick those who have the text equal to $entry
}).remove(); // remove them
$("<li></li>").text($entry) // create a new list item
.appendTo($myList); // add it to $myList
I used the .each function; it iterates through all the items inside the selector. I didn't use .filter, because I though .each would provide a more intuitive programming experience, as you both want to check if something exists and remove it if it does and append that same item to another list.
$myList = $("#myList");
$entry = $("#entry");
$newList = $("#newList");
$entry.on('input', function () {
entryText = $entry.val();
$myList.find("li").each(function () {
if ($(this).html() == entryText) {
$("<li>")
.append($(this).html())
.appendTo($newList);
$(this).remove();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Let's filter some tags<br />
<ul id="myList">
<li>css</li>
<li>js</li>
<li>so</li>
<li>sass</li>
<li>haml</li>
</ul>
<input type="text" id="entry" />
<ul id="newList">
</ul>
I need to add a dropdown where options can be filtered on the fly when on starts to type some word (exactly what Chosen does) AND where a span is always displayed before each option, similar to the Google Drive search bar:
(in this example icons are displayed, but I just need to display a span tag)
"always displayed" in the sense that the span tag should be displayed at the initial display of the dropdown, but also when the list of options starts being filtered, or when an option is selected.
With Chosen I've tried to do this this way:
$select.on("chosen:showing_dropdown", function() {
$(".chosen-results").find('li').each(function(index) {
if(index !== 0) { // ignore the "prompt" li
var courseName = $(this).html();
$(this).html("<span style='color: red'>foo</span> " + courseName);
}
});
});
It works when the dropdown is first displayed by Chosen, but as soon as I start typing something the filtered list of results loses my span tags. I can't find a chosen event that is triggered when the list starts being filtered.
Is there a way to achieve what I need with Chosen, or with any other similar plugin?
If I understood your question correctly then in the <li> element you want to put your span ? Try below:
$select.on("chosen:showing_dropdown", function() {
$(".chosen-results").find('li').each(function(index) {
if(index !== 0) { // ignore the "prompt" li
var courseName = $(this).html();
$(this).prepend("<span style='color: red'>foo</span> " + courseName);
}
});
});
I am trying to have the user check the boxes they are interested in getting resources for and then click the button to get a list of those resources that are hyperlinked to those resources. The hyperlinks (ul id="results” in HTML) are hidden until they called upon by the button “Get Resources”.
Plus I would like to add text to it before results saying “You have indicated an interest in:” (line break) then a listing the hyperlinks (line break) “Please click on the links to learn more”. If no check box is selected the div id=“alert” displays, which I got to work.
I think I am very close, I just can’t seem to get the list of resources.
Here is a link to my coding:
JSFiddle Code sample
$(document).ready(function() {
$('#alert').hide();
$('#results > li').hide();
/* Get the checkboxes values based on the parent div id */
$("#resourcesButton").click(function() {
getValue();
});
});
function getValue(){
var chkArray = [];
/* look for all checkboxes that have a parent id called 'checkboxlist' attached to it and check if it was checked */
$("#checkBoxes input:checked").each(function() {
chkArray.push($(this).val());
});
/* we join the array separated by the comma */
var selected;
selected = chkArray.join(',') + ",";
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if(selected.length > 1){
// Would like it to say something before and after what is displayed
$('#results > li.' + $(this).attr('value')).show();
} else {
$('#alert').show();
}
}
I'd ditch the selected variable and just check the chkArray contents against the list item classes like:
function getValue() {
var chkArray = [];
/* look for all checkboxes that have a parent id called 'checkboxlist' attached to it and check if it was checked */
$("#checkBoxes input:checked").each(function () {
chkArray.push($(this).val());
});
$('#results li').each(function () {
if ($.inArray($(this).attr('class'), chkArray) > -1) $(this).show()
else($(this).hide())
})
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if (!chkArray.length) {
$('#alert').show();
//alert("Please at least one of the checkbox");
}
}
jsFiddle example
I found a straightforward way of achieving what you want. DEMO: https://jsfiddle.net/erkaner/oagc50gy/8/
Here is my approach: I looped through all checkboxes. This way I could get the index of the current item in the original list, i, and use this index to display the corresponding item in the second list. I filter the checked items by using .is(':checked') condition, and then added them item to the array:
function getValue() {
var chkArray = [];
$("#checkBoxes input").each(function (i) {//now we can get the original index anytime
if($(this).is(':checked')){//is the item checked?
chkArray.push($(this).val());//if so add it to the array
var selected;
selected = chkArray.join(", ");
if (selected.length) {
$('#results').find('li').eq(i).show();//show the corresponding link by using `i`
} else {
$('#alert').show();
}
}
});
}
Last thing in your $(document).ready function, add:
$("#checkBoxes input:checkbox").click(function() {
$('li.' + $(this).val().replace(/ /g, '.')).show()
});
JSFiddle
Explanation:
On document ready, add a click handler to the checkboxes that shows the corresponding hidden list item below. The tricky thing here is the spaces in the list names. This makes each word a separate classname, so simply combine the list names with a dot . which results in a sequential classname call in jQuery.
By using <li class="Fitness & Recreation"> as a list item classname, you are giving this item 3 classnames: Fitness, &, and Recreation. In jQuery you select elements with multiple classnames by including each name preceded by a dot .. For example, selecting a list item element with the classnames foo, bar, and baz:
$('li.foo.bar.baz').show()
In the case of <li class="Fitness & Recreation">:
$('li.Fitness.&.Recreation').show()
Since these values are stored in the value attribute of the checkboxes we use jQuery to pull these values: $(this).val(), replace the spaces with dots: .replace(/ /g, '.'), and concatenate the result to the li. portion to access the appropriate list item.
jsFiddle example
I'm attempting to use an ol to display several, dynamic, list items. Upon appending a list item using jQuery, I'd have hoped that the browser would've refreshed the ordered list, however it doesn't appear to be.
<ol>
<li value="1">First</li>
<li value="2">Second</li>
<li value="4">Forth</li>
</ol>
After appending <li value="3">Third</li>, the resulting order is:
// First
// Second
// Forth
// Third <-
Do I need to trigger a re-order, or is the order only calculated upon rendering the page / adding the list DOM element?
Note: I'm using Chrome 28.0.1500.95m
Firstly, note that value is not a valid attribute of li, so your code is invalid. You should use a data attribute for any non-standard attributes you require, the you need to write a sorter function. Try this:
$('#addThird').one('click', function() {
$('ol').append('<li data-value="3">Third</li>');
sortItems();
});
var sortItems = function() {
var $items = $('ol li');
$items.sort(function(a, b) {
var keyA = $(a).data('value');
var keyB = $(b).data('value');
return (keyA > keyB) ? 1 : 0;
});
$.each($items, function(index, row){
$('ol').append(row);
});
}
Updated fiddle
This sorts by the data-value attribute of the element, but that can be amended as required.