Sorting List Items by First Letter - javascript

I am trying to sort list items by their first letter. I am filtering by the .list-title div and then showing the .list-item which holds all of the contents. The problem is, I am using the show method directly on the filter method which is causing nothing to show as it needs to show the .list-item (parent) for the returned results. I am not sure how to rewrite this in any other way. How can I show the list item for each item returned?
$(document).ready(function() {
function filterResults(letter){
$('.list-item').hide();
$('li.list-item .list-title').filter(function() {
return $(this).text().charAt(0).toUpperCase() === letter;
}).show();
};
filterResults('A');
$('a').on('click',function(){
var letter = $(this).text();
filterResults(letter);
});
});
var $listItem = $('.list-item')
$('a').addClass(function(){
var s = this.textContent;
return $listItem.filter(function(){
return this.textContent.charAt(0) === s
}).length ? '' : 'grey';
})
JS Fiddle:
http://jsfiddle.net/2ewgr2mt/2/

You hide .list-item at first which contains everything else.So, when you show .list-title it won't be shown because its parent (.list-item) is hidden. The correct code should be
$(document).ready(function() {
function filterResults(letter){
$('.list-item').hide();
$('.list-item').filter(function() {
return $(this).find('.list-title').text().charAt(0).toUpperCase() === letter;
}).show();
};
filterResults('A');
$('a').on('click',function(){
var letter = $(this).text();
filterResults(letter);
});
var $listItem = $('.list-item')
$('a').addClass(function(){
var s = this.textContent;
return $listItem.filter(function(){
return this.textContent.charAt(0) === s
}).length ? '' : 'grey';
});
});
P/s: Remember to put everything inside ready, and also be careful when using the selector, in your original code you missed . in front of the class name selectors

Related

how to exchange the attribute values simultaneously on single click event using jQuery

I want to replace #cardvieo_localstream with #cardvideo_remotestream at the first click, again I click the same element, I want to change #cardvideo_remotestream back #cardvieo_localstream, I'm not sharp at jQuery yet, but I'm trying to learn. I appreciate all help I can get.
I've try this code but working on first click. but not working on second click
$('.video-list .videoWrap').on('click', function() {
var $thisVideoWrap = $(this).find('.video-list .videoWrap');
var $mainVideoWrap = $('.mainVideoWrap');
if ($(this).attr('id') === '#cardvideo_localStream') {
$(this).attr('id', '#cardvideo_remotestream');
}
else if($(this).attr('id') == '#cardvideo_localStream') {
$(this).attr('id', '#cardvideo_local');
$mainVideoWrap.attr('id', 'cardvideo_remotestream');
}
});
Don't change An Id Attribute because of id is a unique value Only use the Classname, I swap the elements successfully
// using jQuery
var initVideoSwapping = function () {
// check if there is an element first
if ($('.video-list .videoWrap').length > 0) {
$('.video-list .videoWrap').on('click', function () {
var $thisVideo = $(this).find('video')[0];
var $mainVideo = $('.mainVideoWrap').find('video')[0];
swapNodes($thisVideo, $mainVideo)
});
}
}
function swapNodes(a, b) {
var aparent = a.parentNode;
var asibling = a.nextSibling === b ? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
$(function () {
initVideoSwapping();
});

Parent siblings not showing after hiding/showing

I have a simple in-page search function which shows only topics which contain words searched for.
Each section has a heading, a <h2> - I want the headings for the blocks which are not hidden, to show.
The problem: The h2 header does not always show after the search
This is a fiddle to test the issue
Fail/success examples:
One of the headings is Complaints and cancellations - sub section titled: How do I cancel
If you search for how do then you'll see the first block show, with header... the second block titled Guides disappears. This is correct.
If you search for I cancel - again, the second block disappears, which is correct, but, the heading for the first block hides too, which it shouldn't.
This is the javascript:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).parent().parent().parent().siblings('h2').hide();
$(this).fadeOut();
} else {
$(this).fadeIn('fast', function(){
$(this).parent().parent().parent().siblings('h2').show();
});
}
});
});
Is there a better way to do this?
The problem is that a hide of the h2 can occur after a show for the same section, depending on the order of matches in the section.
The quick solution is to do all the hides first, then the shows:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).closest('.vc_tta').siblings('h2').hide();
$(this).fadeOut();
}
});
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v == "" || eachPlace.search(v) > -1) {
$(this).fadeIn('fast', function(){
$(this).closest('.vc_tta').siblings('h2').show();
});
}
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/L0m3z98y/2/
Notes:
parent().parent().parent() is a not a maintainable solution. Any change to the DOM structure will break the code. Instead use closest() with an appropriate target selector. This is shorter and safer

Result not showing in Input text

I have the following JQuery code I am working on. When I test it, the expected values are shown in the span but not in the input text box.
JQ
$(function() {
$("#textbox").each(function() {
var input = '#' + this.id;
counter(input);
$(this).keyup(function() {
counter(input);
});
});
});
function counter(field) {
var number = 0;
var text = $(field).val();
var word = $(field).val().split(/[ \n\r]/);
words = word.filter(function(word) {
return word.length > 0 && word.match(/^[A-Za-z0-9]/);
}).length;
$('.wordCount').text(words);
$('#sentencecount').text(words);
}
Please see Fiddle. Please let me know where I have gone wrong. Still new to JS.
Thanks
Change this:
$('#sentencecount').text(words);
to this:
$('#sentencecount').val(words);
The .text() method cannot be used on form inputs or scripts. To set or get the text value of input or textarea elements, use the .val() method. To get the value of a script element, use the .html() method. -> http://api.jquery.com/text/
Trying using val() instead This should fix it up.
http://jsfiddle.net/josephs8/6B9Ga/8/
You can not set text to an input you must use value
try this.
$('#sentencecount').text(words);
//has to be
$('#sentencecount').val(words);
and i have also updated your Jsfiddle
$(function() {
$("#textbox").each(function() {
var input = '#' + this.id;
counter(input);
$(this).keyup(function() {
counter(input);
});
});
});
function counter(field) {
var number = 0;
var text = $(field).val();
var word = $(field).val().split(/[ \n\r]/);
words = word.filter(function(word) {
return word.length > 0 && word.match(/^[A-Za-z0-9]/);
}).length;
$('.wordCount').text(words);
$('#sentencecount').val(words);
}

How to match children innerText with user input using jQuery

I have the following structure:
<div id="campaignTags">
<div class="tags">Tag 1</div>
<div class="tags">Tag 2</div>
<div class="tags">Tag 3</div>
</div>
And I'm trying to match user input against the innerText of each children of #campaignTags
This is my latest attempt to match the nodes with user input jQuery code:
var value = "Tag 1";
$('#campaignTags').children().each(function(){
var $this = $(this);
if(value == $(this).context.innerText){
return;
}
The variable value is for demonstration purposes only.
A little bit more of context:
Each div.tags is added dynamically to div#campaignTags but I want to avoid duplicate values. In other words, if a user attempts to insert "Tag 1" once again, the function will exit.
Any help pointing to the right direction will be greatly appreciated!
EDIT
Here's a fiddle that I just created:
http://jsfiddle.net/TBzKf/2/
The lines related to this question are 153 - 155
I tried all the solutions, but the tag is still inserted, I guess it is because the return statement is just returning the latest function and the wrapper function.
Is there any way to work around this?
How about this:
var $taggedChild = $('#campaignTags').children().filter(function() {
return $(this).text() === value;
});
Here's a little demo, illustrating this approach in action:
But perhaps I'd use here an alternative approach, storing the tags within JS itself, and updating this hash when necessary. Something like this:
var $container = $('#campaignTags'),
$template = $('<div class="tags">'),
tagsUsed = {};
$.each($container.children(), function(_, el) {
tagsUsed[el.innerText || el.textContent] = true;
});
$('#tag').keyup(function(e) {
if (e.which === 13) {
var tag = $.trim(this.value);
if (! tagsUsed[tag]) {
$template.clone().text(tag).appendTo($container);
tagsUsed[tag] = true;
}
}
});
I used $.trim here for preprocessing the value, to prevent adding such tags as 'Tag 3 ', ' Tag 3' etc. With direct comparison ( === ) they would pass.
Demo.
I'd suggest:
$('#addTag').keyup(function (e) {
if (e.which === 13) {
var v = this.value,
exists = $('#campaignTags').children().filter(function () {
return $(this).text() === v;
}).length;
if (!exists) {
$('<div />', {
'class': 'tags',
'text': v
}).appendTo('#campaignTags');
}
}
});
JS Fiddle demo.
This is based on a number of assumptions, obviously:
You want to add unique new tags,
You want the user to enter the new tag in an input, and add on pressing enter
References:
appendTo().
filter().
keyup().
var value = "Tag 1";
$('#campaignTags').find('div.tags').each(function(){
if(value == $(this).text()){
alert('Please type something else');
}
});
you can user either .innerHTML or .text()
if(value === this.innerHTML){ // Pure JS
return;
}
OR
if(value === $this.text()){ // jQuery
return;
}
Not sure if it was a typo, but you were missing a close } and ). Use the jquery .text() method instead of innerText perhaps?
var value = "Tag 1";
$('#campaignTags').find(".tags").each(function(){
var content = $(this).text();
if(value === content){
return;
}
})
Here you go try this: Demo http://jsfiddle.net/3haLP/
Since most of the post above comes out with something here is another take on the solution :)
Also from my old answer: jquery - get text for element without children text
Hope it fits the need ':)' and add that justext function in your main customised Jquery lib
Code
jQuery.fn.justtext = function () {
return $(this).clone()
.children()
.remove()
.end()
.text();
};
$(document).ready(function () {
var value = "Tag 1";
$('#campaignTags').children().each(function () {
var $this = $(this);
if (value == $(this).justtext()) {
alert('Yep yo, return');)
return;
}
});
//
});

jQuery - Find any input with a given class that has no value

I have a (very) basic validation script. I basically want to check for any inputs with class .required to see if there values are a) blank or b) 0 and if so, return false on my form submit. This code does not seem to return false:
function myValidation(){
if($(".required").val() == "" || $(".required").val() == 0){
$(this).css({ backgroundColor:'orange' }) ;
return false;
}
}
Appending this function to my onSubmit handler of my form is not returning any results. Any light shed on this matter will be appreciated.
I am basically after a function that iterates through all the inputs with class .required, and if ANY have blank or 0 values, return false on my submit and change the background colour of all badly behaved inputs to orange.
Your code currently gets the .val() for the first .required, from the .val() documentation:
Get the current value of the first element in the set of matched elements.
You need to filter through each one individually instead, like this:
function myValidation(){
var allGood = true;
$(".required").each(function() {
var val = $(this).val();
if(val == "" || val == 0) {
$(this).css({ backgroundColor:'orange' });
allGood = false;
}
});
return allGood;
}
Or a bit more compact version:
function myValidation(){
return $(".required").filter(function() {
var val = $(this).val();
return val == "" || val == 0;
}).css({ backgroundColor:'orange' }).length === 0;
}
Try this jQuery selector:
$('.required[value=""], .required[value=0]')
You could also do it by defining your own custom jQuery selector:
$(document).ready(function(){
$.extend($.expr[':'],{
textboxEmpty: function(el){
return ($(el).val() === "");
}
});
});
And then access them like this:
alert($('input.required:textboxEmpty').length); //alerts the number of input boxes in your selection
So you could put a .each on them:
$('input.required:textboxEmpty').each(function(){
//do stuff
});

Categories