0

I am trying to removeClass from "li" but it doesn't work. Here is my function:

function setStore($s, id, name) {
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);
    $s.parents('ul.popup-cbo-menu').find('li.selected').removeClass('selected');
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);

    //$s.parent('li').addClass('selected');
    $('#cboStores').val(name);
}

I can confirm that the "selected" is removed by putting alert. But for some reason, it doesn't affect the actual "li".

Here is the jsfiddle: http://jsfiddle.net/87xswem7/9/. However, but for some reason, jsFiddle is unable to find setStore() function.

Here is how I create the popover:

$(document).ready(function () {
    $("#cboStores").popover({
        viewport: 'body',
        trigger: 'click',
        placement: 'bottom',
        html: true,
        content: '<ul class="popup-cbo-menu">' +
                 '   <li><a href="#" onclick="setStore($(this), -1, \'All Stores\')">All Stores</a></li>' + 
                 '   <li class="selected"><a href="#" onclick="setStore($(this), 1, \'My Foot\')">My Foot</a></li>' +
                 '   <li><a href="#" onclick="setStore($(this), 2, \'My Foot 1\')">My Foot 1</a></li>' +
                 '</ul>',
        template: '<div class="popover cont-popup-cbo-menu" role="tooltip">' +
                  '   <div class="arrow"></div><h3 class="popover-title"></h3>' +
                  '   <div class="popover-content"></div>' +
                  '</div>'
    }).blur(function () {
        $(this).popover('hide');
    });
});

And here is my input box in html:

<input type="text" id="cboStores" value="My Foot" />
Universal Electricity
  • 775
  • 1
  • 12
  • 26
Sam
  • 1,826
  • 26
  • 58

3 Answers3

2

The main problem you're having is that you're trying to use your setStore function to modify the content of a popover assuming that it exists normally in the DOM:

function setStore($s, id, name) {
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);
    $s.parents('ul.popup-cbo-menu').find('li.selected').removeClass('selected');
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);

    //$s.parent('li').addClass('selected');
    $('#cboStores').val(name);
}

However, the content of your popover, as defined, does not exist in the DOM the way you expect. The content is actually a property of the popover and can be logged as such:

console.log($("#cboStores").data('bs.popover').options.content)

Now, in order to do what you would like, you will have to be able to dynamically modify the contents of the popover.

Here is a post I referenced to do just that: Bootstrap popover content cannot changed dynamically

So, what I did is remove the HTML content semantics from your javascript and I put it directly into the HTML to be manipulated by the javascript:

<input type="text" id="cboStores" placeholder="Select Store" value="My Foot" style="width:150px;height:30px;" />

<div id="popoverContent" class="hidden">
    <ul class="popup-cbo-menu">
        <li><a href="#" onclick="setStore($(this), -1, 'All Stores')">All Stores</a></li>
        <li class="selected"><a href="#" onclick="setStore($(this), 1, 'My Foot')">My Foot</a></li>
        <li><a href="#" onclick="setStore($(this), 2, 'My Foot 1')">My Foot 1</a></li>
    </ul>
</div>

Notice I wrapped everything in a hidden div which will be used to reference the popover content. Now, the new setStore function looks like this:

function setStore($s, id, name) {                                                               
    $('#popoverContent').find('li.selected').removeClass('selected');
    $('#popoverContent').find('a').filter(function(){
        return $(this).text() === $s[0].innerHTML;
    }).parent().addClass('selected');
    $('#cboStores').val(name);
    $("#cboStores").data('bs.popover').options.content = $('#popoverContent').html();
}

And the popover content in the initialization of the popover in the javascript is changed to:

$('#popoverContent').html()

This way, what you're actually doing is modifying the content of the HTML and then setting the content of the popover to reflect the changes in the HTML.

Fiddle: http://jsfiddle.net/87xswem7/12/

Community
  • 1
  • 1
Dennis G.
  • 283
  • 1
  • 11
  • Note that jsfiddle doesn't work, you need to put in $(document).ready(function () { }); and set jsfiddle to "No wrap - in ". This works for me http://jsfiddle.net/87xswem7/13/ – Sam Oct 13 '15 at 09:18
  • It worked just fine for me in the fiddle I provided at the end of my answer: http://jsfiddle.net/87xswem7/12/. I'm glad I could help! :) – Dennis G. Oct 13 '15 at 10:16
1

I know why:

For your fiddle, you already wrapped the JS in the onload:

enter image description here

However, you do it again:

$(document).ready(function () {
  //...
}

There's no need for that. Simply change it to no wrap.

enter image description here

Universal Electricity
  • 775
  • 1
  • 12
  • 26
0

use

setStore = function($s, id, name) {
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);
    $s.parents('ul.popup-cbo-menu').find('li.selected').removeClass('selected');
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);

    //$s.parent('li').addClass('selected');
    $('#cboStores').val(name);
}

rather than

function setStore($s, id, name) {
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);
    $s.parents('ul.popup-cbo-menu').find('li.selected').removeClass('selected');
    //alert("length: " + $s.parents('ul.popup-cbo-menu').find('li.selected').length);

    //$s.parent('li').addClass('selected');
    $('#cboStores').val(name);
}

it solved for me (fiddle)

guiligan
  • 369
  • 4
  • 17