Link to home
Start Free TrialLog in
Avatar of Dean OBrien
Dean OBrienFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Updating checkbox via JQuery does not trigger Knockout binding

Experts,

I am using knockout.js on a project to show/hide articles, based on what tag (checkbox) has been selected. My problem arises however, when i try to trigger the checked / unchecked status of a tag, using some jquery code elsewhere in the page.

The code is successfully check/unchecking the box, however the observable array that the checkboxes are bound to in knockout is not then getting updated.

I have attached a code snippet of code. First try checkbox at top, then the tags in bold. You will see the checkbox then gets selected, but no update on knockout.
<!DOCTYPE HTML>
<html>
<body>
<style>
.news-block {width: 250px;}
</style>
<div id="latest-news">
    <div>
        <h1>News</h1>
        <div class="row">
            <div id="tags">
                <h2>Tagged in:</h2>
                <div class="tags">
                        <label><input type="checkbox" value="general" id="general-tag-checkbox" data-bind="checked: tags" /><span class="tag general-tag" id="general-tag" >general</span></label>
                        <label><input type="checkbox" value="accomodation" id="accomodation-tag-checkbox" data-bind="checked: tags " /><span class="tag accomodation-tag" id="accomodation-tag" >accomodation</span></label>
                        <label><input type="checkbox" value="careers" id="careers-tag-checkbox" data-bind="checked: tags " /><span class="tag careers-tag" id="careers-tag" >careers</span></label>
                        <label><input type="checkbox" value="catering" id="catering-tag-checkbox" data-bind="checked: tags " /><span class="tag catering-tag" id="catering-tag" >catering</span></label>
                        <label><input type="checkbox" value="retail" id="retail-tag-checkbox" data-bind="checked: tags " /><span class="tag retail-tag" id="retail-tag" >retail</span></label>
                        <label><input type="checkbox" value="sport" id="sport-tag-checkbox" data-bind="checked: tags " /><span class="tag sport-tag" id="sport-tag" >sport</span></label>
                </div>
            </div>
        </div>

        <div id="news" data-bind='template: { foreach: articlesToShow, afterMove: afterMove }'>
            <div class="news-block large-3 medium-6 columns">
                <a data-bind="attr: { href: LinkToPage }" class="news-item">
                    <div class="news-img" data-bind="style: { backgroundImage: 'url(\'' + ImageUrl + '\')' }">
                        <div class="title">
                            <h3><strong data-bind="text: Title"></strong></h3>
                        </div>
                    </div>
                </a>
                <div class="news-content">
                    <p data-bind="text: Excerpt"></p>
                    <p data-bind="text: PublishedDate"></p>
                    <div class="tags" data-bind='foreach: Categories'>
                        <b><span data-bind="text: $data, attr: {text: $data, class: $data+'-tag'}"></span></b>
                    </div>
                </div>

            </div>
        </div>
    </div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js'></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js'></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.0/masonry.pkgd.min.js'></script>
<script>
$(document).ready(function () {

	$container = $('#news');
	$container.masonry({});

	$("[class$=-tag]").click(function (event) {
		if($(event.target).attr('class').indexOf(' ') >= 0){}
		else{
			var x="#"+$(event.target).attr('class');
			var y=x+"-checkbox";

			if($(y)[0].checked == false){
				alert("adding " + y);
				//$(y)[0].checked = true;
			}else{
				alert("removing "+ y);
				//$(y)[0].checked = false;		
			}
			$(x).click();
		}
	});

	$(".tag").click(function () {
	    if ($(this).hasClass('active')) {
	        $(this).removeClass('active');
	    }
	    else {
	        $(this).addClass('active');
	    }
	});
});

var NewsModel = function() {
	this.tags = ko.observableArray([]);
	this.newsArticles = ko.observableArray([{"Title":"xxx","ImageUrl":"xxx.jpg","ImageAlt":"xxx","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"6 days ago","LinkToPage":"xxx","Categories":["accomodation","careers"]},{"Title":"xxx","ImageUrl":"xxx","ImageAlt":"xxx","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["careers","general"]},{"Title":"New News Article","ImageUrl":"xxx","ImageAlt":"","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["retail"]},{"Title":"New News Article","ImageUrl":"xxx","ImageAlt":"","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["catering"]},{"Title":"ddddd","ImageUrl":"xxx","ImageAlt":"","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["sport"]},{"Title":"qqq","ImageUrl":"xxx","ImageAlt":"","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit.","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["sport"]},{"Title":"yyy","ImageUrl":"xxx","ImageAlt":"xxx","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convalli non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit. ","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["careers","catering","general"]},{"Title":"xxx","ImageUrl":"xxx","ImageAlt":"xxx","Excerpt":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus justo mi, ut vestibulum velit convallis non. Nam dictum congue arcu, et suscipit dolor convallis id. Duis vel diam dignissim elit congue rutrum. Integer tristique eu nibh id tincidunt. In interdum enim nibh, ut dictum dui condimentum sit amet. Duis scelerisque congue tristique. Quisque interdum, odio eu tristique iaculis, nisl libero efficitur urna, sit amet finibus tortor nibh nec erat. Ut tincidunt augue ac lacus euismod blandit. ","PublishedDate":"3 days ago","LinkToPage":"xxx","Categories":["retail"]}]);
	this.afterMove = function(element, index, data) {$container.masonry( 'reloadItems' );$container.masonry( 'layout' );};
    this.articlesToShow = ko.computed(function() {
		var desiredArray = this.tags();

		if (_.isEmpty(desiredArray)) return this.newsArticles();

        return ko.utils.arrayFilter(this.newsArticles(), function(newsArticle) {
            return !_.isEmpty(_.intersection(newsArticle.Categories, desiredArray));
        });
    }, this);

};

ko.applyBindings(new NewsModel(), document.getElementById('latest-news'));

</script>
</body>
</html>

Open in new window


Any suggestions on getting this to update the knockout array would be appreciated.

Regards
Dean
Avatar of Dorababu M
Dorababu M
Flag of India image

Hi I am seeing some news getting loaded when I check the check boxes, what was not working in this
User generated image
On checking general checkbox
general.PNG
Avatar of Dean OBrien

ASKER

Hi Dorababu,

The boxes at the top work fine.

Whats now working is if you click the bold tags at the bottom of the article (i.e. accommodation in first one), ehich causes the alert('Adding xxxx'). It causes the accomodation checkbox at the top to be ticked, but not the knockout to show hide articles.

Regards
Dean
OK if I got you correctly when you click on the bold text and if checkbox got unchecked you need to hide the respective posts?
The behaviour when you  'check' and then 'uncheck' GENERAL bold tab on a news article, should be the same as when you 'check' and then 'uncheck' GENERAL checkbox in the top group.

Does that make sense?

The top boxes work correctly, then tabs in the articles do not work correctly.

Regards
Dean
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Rob,
I have reviewed and that works perfectly. Really helped me out thanks!
Cheers
Dean