Owl carousel and knockout.js binding within foreach binding - javascript

He everyone, I know it is going to be specific question, but I have a problem using owl carousel with knockout.
<div class="row">
<div id="owl-example" class="owl-carousel" data-bind="foreach: ads">
<div class="ad-module">
<div data-bind="attr: { src: '/Content/images/' + Image }"></div>
<div data-bind="text: Title"></div>
<div data-bind="text: CityName"></div>
<div data-bind="text: CategoryName"></div>
</div>
</div>
</div>
If I delete owl-carousel class, everything works. And if I delete knockout foreach and enter images manually everything works. Did anyone ever had this problem before? Thanks.

You can call a specific function after you finish rendering the foreach items using:
<div data-bind="foreach: items, someOtherFunction">
The function that you want to call should be defined in ko.bindingHandlers
Here is a working example:
ko.bindingHandlers.owlCarouselInitiator = {
init: function() {
$('.owl-carousel').owlCarousel({
loop:true,
nav:true,
items : 3,
itemsDesktop : [1000,3],
itemsDesktopSmall : [900,3],
itemsTablet: [600,3]
})
}
};
ko.applyBindings({
items: ko.observableArray([
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"9",
"10"
])
});
body {
margin: 0;
padding: 0;
}
ul {
margin: 0;
padding: 0;
}
.owl-carousel .item {
height: 120px;;
background: #4DC7A0;
padding: 1rem;
list-style: none;
margin: 10px;
}
.owl-carousel .item h4 {
color: white;
text-align: center;
padding-top: 20px;
font-size: 25px;
line-height: 120px;
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.min.js"></script>
<ul class="owl-carousel" data-bind="foreach: items, owlCarouselInitiator">
<li class="item"><h4 data-bind="text: $data"></h4></li>
</ul>

If you need dynamically change items after view is rendered you can use custom knockout binding from https://github.com/OleksiiStepanov/KnockoutOwlCarousel2
Usage example:
<div class="owl-carousel owl-theme" data-bind="owlCarousel: {data: items, options:{margin:10, nav:true }}">
<div class="item" data-bind="text: $data"></div>
</div>
Live demo http://jsfiddle.net/s2reh01L/5/

You can also you the afterRender callback to run initialise your owl carousel once your foreach has rendered.
<ul data-bind="foreach: { data: myItems, afterRender: initOwlCarousel }">
<li data-bind="text: $data"></li>
</ul>

Related

modify handlebars template with javascript/jquery

I have a handlebars template such as this
<script type="text/html" id="some-id">
<div class="some-class-1" {{#if some_condition}}style="color:blue;"{{/if}}>
</div>
<div class="some-class-2">
<div class="some-nested-class-1">
</div>
</div>
<div class="some-class-3">
</div>
</script>
I want to modify this template for example add another div after div.some-nested-class-1
I used the following code, to parse the template to dom
jQuery(function ($) {
var t = $("#some-id");
var d = $("<div>").html(t.html());
console.log(d.html());
});
but it changes {{#if}} as follows :
<div class="some-class-1" {{#if="" some_condition}}style="color:blue;" {{="" if}}="">
</div>
<div class="some-class-2">
<div class="some-nested-class-1">
</div>
</div>
<div class="some-class-3">
</div>
Using Chrome and jsfiddle here https://jsfiddle.net/wv7hzx5a/
How can I achieve this without affecting the template?
Many thanks
PS: the template is being compiled in a separate script which I do not have access to change. I want to modify the template so that when the other script compiles it, the new elements will be included.
I don"t understand what you're trying to to and what you mean by parse the template to DOM. If you want to process the template and replace the handlebar code to have html, then use handlebar to do it and not jQuery. Only handlebar can interpret and translate the handlebar instructions to have the result. Then once that you have your result you can display it with jQuery if you want. Here is one example :
var context = {
"mydata": [
{
"character-id": "Luke1",
"firstname": "Luke",
"name": "Skywalker",
"age": "20",
"rebel": true
},
{
"character-id": "Leia1",
"firstname": "Leia",
"name": "Organa",
"age": "20",
"rebel": true
},
{
"character-id": "Vader1",
"firstname": "Darth",
"name": "Vader",
"age": "45",
"rebel": false
}
]
}
// Here you process the template and put it in the DOM
var template = $('#handlebars-demo').html();
var templateScript = Handlebars.compile(template);
var html = templateScript(context);
$("#placeholder").append(html);
// Once you have inserted your code in the DOM you can now use jQuery to modify it
// For example I put a star after Leia's section
$("#Leia1").html($("#Leia1").html()+"*")
</script>
.some-class-1 {
padding: 10;
min-width: 10px;
min-height: 20px;
border: solid blue 1px;
}
.some-class-2 {
padding: 10;
min-width: 10px;
min-height: 20px;
border: solid black 1px;
}
.some-class-3 {
padding: 10;
min-width: 10px;
min-height: 20px;
border: solid green 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.min.js"></script>
<script type="text/html" id="handlebars-demo">
{{#each mydata}}
<div id="{{character-id}}">
<div class="some-class-1" {{#if rebel}}style="color:blue;"{{/if}}>
{{firstname}}
</div>
<div class="some-class-2" {{#if rebel}}style="color:blue;"{{/if}}>
{{name}}
</div>
<div class="some-class-3">
<div class="some-nested-class-1">
{{age}}
</div>
</div>
</div>
<br/>
{{/each}}
</script>
<div id="placeholder"></div>

Modifying JS pager - how to substitute html elements using JQuery

Here is the initial code:
<div class="fs-table-table">
<div class="fs-table-row header">
<div class="fs-table-cell">
Course Name
</div>
<div class="fs-table-cell">
Lessons
</div>
</div>
<div id="fs-table-content">
</div>
</div>
Now the pager file calls:
$('#' + options.contentHolder).html(template(pager, options.template, options.currentData, options.startPage, options.perPage, options.alwaysShowPager, options.informationToShow, options.errorTemplate));
where contentHolder is 'fs-table-content', and it points to a template:
<script type="text/template" id="weeklyLessonTemplate">
<div class="fs-table-row">
<div class="fs-table-cell" data-title="Course Name">
##courseName##
</div>
<div class="fs-table-cell" data-title="Lesson">
<input type="radio" class="radio" name="weekly_lesson" value="##lessons##" />
<label for="##lessons##">##lessons##
</label>
</div>
</div>
</script>
and it yields:
<div class="fs-table-table">
<div class="fs-table-row header">
<div class="fs-table-cell">
Course Name
</div>
<div class="fs-table-cell">
Lessons
</div>
</div>
<div class="fs-table-row">
<div class="fs-table-cell" data-title="Course Name">
Art/Music/Social Media
</div>
<div class="fs-table-cell" data-title="Lesson">
<input type="radio" class="radio" name="weekly_lesson" value="What is art?">
<label for="What is art?">What is art?
</label>
</div>
</div>
</div>
So you see, calling the function "template" simply returns html code. Now, when I click on the next page number, I expect the html to change but it doesn't change, it stays the same because
<div id="fs-table-content">
</div>
has been replaced. How do I inject fs-table-content back into the code. It should be put in the page onclick code:
$('#' + pager).on('click', '.page, .last-page, .first-page, .next-pages, .prev-pages', function(e) {
var newPage = parseInt($(this).data('value'));
var perPage = parseInt($('#' + pager + ' .perPage').val());
$('#' + pager + ' .page.current').removeClass('current');
$('#' + pager + ' .page[data-value="' + newPage + '"]').addClass('current');
showProperPaging(pager, newPage, options.totalPages, options.pagesToShow);
$('#' + options.contentHolder).html(template(pager, options.template, options.currentData, newPage, perPage, options.alwaysShowPager, options.informationToShow, options.errorTemplate));
options.currentPage = newPage;
$('#' + pager).trigger("pagingChange");
});
I noticed that in the demo for the pager, they use the following line to change the html:
var showing = $('#' + templateToShow).html().format(data);
html += showing;
But my data is structured differently, I don't think I can use .format
The way this script has been designed is that you need to provide two separate divs (not nested within one another). One for your content and one of its content (where it places pagination, search .. etc).
So you can change your code to this for it work:
!function(a){function e(e,t,r,n,o,s,g){var p="",l=Math.ceil(t/r);p+='<div class="showing"></div>',p+='<div class="pager"><span class="first-page btn" data-value="1">First</span><span class="prev-page btn">Previous</span><span class="prev-pages btn" data-value="1">...</span><span class="page btn current" data-value="1">1</span>';for(var i=1;i<l;i++)p+='<span class="page btn" data-value="'+(i+1)+'">'+(i+1)+"</span>";p+='\t<span class="next-pages btn" data-value="6">...</span><span class="next-page btn">Next</span><span class="last-page btn" data-value="'+l+'">Last</span></div>',p+='<div class="options" style="text-align: center; margin-bottom: 10px;"><span>Show </span><select class="perPage">';for(i=0;i<n.length;i++)n[i]==r?p+='<option selected="selected">'+n[i]+"</option>":p+="<option>"+n[i]+"</option>";p+="\t</select><span> per page</span></div>",s&&(p+='<div class="searchBox"><input type="text" class="search" placeholder="Search" value="'+g+'" /></div>'),a("#"+e).html(p)}function t(e,t,r,n){1==t?a("#"+e).find(".prev-page").hide():a("#"+e).find(".prev-page").show(),t==r?a("#"+e).find(".next-page").hide():a("#"+e).find(".next-page").show();var o,s,g=n,p=Math.ceil(g/2),l=Math.floor(g/2);r<g?(o=0,s=r):t>=1&&t<=p?(o=0,s=g):t+l>=r?(o=r-g,s=r):(o=t-p,s=t+l),a("#"+e+" .pager").children().each(function(){a(this).hasClass("page")&&a(this).hide()});for(var i=o;i<s;i++)o>0?(a("#"+e+" .prev-pages").show(),a("#"+e+" .prev-pages").data("value",o)):a("#"+e+" .prev-pages").hide(),a("#"+e+" .page[data-value='"+(i+1)+"']").show(),s<r?(a("#"+e+" .next-pages").show(),a("#"+e+" .next-pages").data("value",s+1)):a("#"+e+" .next-pages").hide();1==r?a("#"+e+" .last-page, #"+e+" .first-page").hide():0==r?a("#"+e+" .pager, #"+e+" .showing, #"+e+" .options").hide():(a("#"+e+" .pager, #"+e+" .showing, #"+e+" .options").show(),a("#"+e+" .last-page, #"+e+" .first-page").show())}function r(e,t,r,n,o,s,g,p){var l="",i=n*o-(o-1),h=n*o>r.length?r.length:n*o;if(r.length<=0){if(""==p)l+='<div class="dataError">There is nothing to show here.</div>';else l+=a("#"+p).html().format(["There are no Messages to display."]);return s||a("#"+e).hide(),l}a("#"+e).show(),a("#"+e+" .showing").html("Showing "+i+" to "+h+" of "+r.length+" total.");for(var c=n*o-o;c<n*o&&c!=r.length;c++){var u=[];a.each(g,function(a,e){u.push(r[c][e])}),l+=a("#"+t).html().format(u)}return l}a.fn.extend({paging:function(n){var o={data:{},contentHolder:"",template:"",errorTemplate:"",informationToShow:[],informationToRefineBy:[],perPage:10,pageLengths:[5,10,20,30,40,50],startPage:1,pagesToShow:5,showOptions:!0,showSearch:!0,alwaysShowPager:!0},s={currentPage:o.startPage,totalPages:0,currentData:n.data,refine:""};n=a.extend(o,n),(n=a.extend(s,n)).totalPages=Math.ceil(n.currentData.length/n.perPage),function(n,o){o.totalPages;e(n,o.currentData.length,o.perPage,o.pageLengths,o.showOptions,o.showSearch,o.refine),t(n,o.startPage,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,o.startPage,o.perPage,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),a("#"+n).on("click",".page, .last-page, .first-page, .next-pages, .prev-pages",function(e){var s=parseInt(a(this).data("value")),g=parseInt(a("#"+n+" .perPage").val());a("#"+n+" .page.current").removeClass("current"),a("#"+n+' .page[data-value="'+s+'"]').addClass("current"),t(n,s,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,s,g,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),o.currentPage=s,a("#"+n).trigger("pagingChange")}),a("#"+n).on("click",".next-page",function(e){var s=o.currentPage+1,g=parseInt(a("#"+n+" .perPage").val());a("#"+n+" .page.current").removeClass("current"),a("#"+n+' .page[data-value="'+s+'"]').addClass("current"),t(n,s,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,s,g,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),o.currentPage=s,a("#"+n).trigger("pagingChange")}),a("#"+n).on("click",".prev-page",function(e){var s=o.currentPage-1,g=parseInt(a("#"+n+" .perPage").val());a("#"+n+" .page.current").removeClass("current"),a("#"+n+' .page[data-value="'+s+'"]').addClass("current"),t(n,s,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,s,g,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),o.currentPage=s,a("#"+n).trigger("pagingChange")}),a("#"+n).on("change",".perPage",function(s){var g=parseInt(a(this).val());e(n,o.data.length,g,o.pageLengths,o.showOptions,o.showSearch,o.refine),o.totalPages=Math.ceil(o.currentData.length/g),t(n,o.startPage,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,o.startPage,g,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),o.currentPage=o.startPage,a("#"+n).trigger("pagingChange")}),a("#"+n).on("keyup",".search",function(e){var s=parseInt(a("#"+n+" .perPage").val()),g=a(this).val();o.refine=g;var p=function(e,t,r){if(""==t)return;var n=t.toLowerCase();dataToKeep=[];for(var o=0;o<e.length;o++)a.each(r,function(a,t){if(null!=e[o][t]&&e[o][t].toLowerCase().indexOf(n)>=0)return dataToKeep.push(e[o]),!1});return dataToKeep}(o.data,g,o.informationToRefineBy);p||(p=o.data),o.currentData=p;var l=Math.ceil(o.currentData.length/s);o.totalPages=l,t(n,o.startPage,o.totalPages,o.pagesToShow),a("#"+o.contentHolder).html(r(n,o.template,o.currentData,o.startPage,s,o.alwaysShowPager,o.informationToShow,o.errorTemplate)),a("#"+n).trigger("pagingChange")}),a("#"+n).on("focusin",".search",function(){o.refineFocus=!0}),a("#"+n).on("focusout",".search",function(){o.refineFocus=!1})}(a(this).attr("id"),n)}})}(jQuery),String.prototype.format=function(){var a=arguments;return this.replace(/{(\d+)}/g,function(e,t){return void 0!==a[0][t]?a[0][t]:e})};
$(document).ready(function() {
var data = [{
"firstname": "John",
"lastname": "Smith"
}, {
"firstname": "Jane",
"lastname": "Doe"
}, {
"firstname": "James",
"lastname": "Smith"
}, {
"firstname": "Amanda",
"lastname": "Doe"
}, {
"firstname": "Billy",
"lastname": "Joe"
}];
$('#fs-table-table').paging({
data: data, //This is the data that is being used. It is using JSON data so you can pull from any source if you want.
contentHolder: 'fs-table-content', //The id for the area where you want the data to be displayed.
template: 'weeklyLessonTemplate', //The template that is being used to display the data.
errorTemplate: 'contentErrorTemplate', //The error template that is being used (optional)
informationToShow: ['firstname', 'lastname'], //The information that you want to show from the given data
informationToRefineBy: ['firstname', 'lastname'], //The information that you want to search on from the given data
perPage: 1, //Default number to show per page. (Since we have a small amount of data only show 1.)
pageLengths: [1, 2, 3, 4], //Options for number of items per page.
startPage: 1, //The default start page. (Better to leave as 1 but can be changed if desired).
pagesToShow: 4, //Number of pages to show at the top. If you have 10 pages it will show [...] when going above or below the this number.
showOptions: true, //Show the per page options.
showSearch: true, //Show the search bar.
alwaysShowPager: true //Show the pager even if there isn't any data. Should be true if showSearch is true otherwise there will be problems.
});
});
.pager span.current {
border: red;
border-radius: 5px;
font-weight: bold;
color: red;
}
.dataError {
width: 100%;
font-size: 20px;
text-align: center;
padding: 10px;
}
.searchBox {
width: 300px;
margin: 0 auto;
}
.searchBox .search {
width: 100%;
height: 30px;
}
.showing {
width: 100%;
text-align: center;
}
.dropdown:hover .dropdown-menu { display: block; }
.pager span {
border-radius: 5px;
border: #a6a6a8 1px solid;
padding: 5px 14px;
margin: 0 3px;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.pager span:hover { background-color: #ddd; }
.pager span.current:hover {
background-color: #fff;
cursor: default;
}
.pager {
padding-left: 0;
margin: 20px 0;
text-align: center;
list-style: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="fs-table-content"></div>
<div id="fs-table-table"></div>
<script type="text/template" id="weeklyLessonTemplate">
<div class="fs-table-row header">
<div class="fs-table-cell">
Course Name
</div>
<div class="fs-table-cell">
Lessons
</div>
</div>
<div id="fs-table-content">
<div class="fs-table-row">
<div class="fs-table-cell" data-title="Course Name">
{0}
</div>
<div class="fs-table-cell" data-title="Lesson">
<input type="radio" class="radio" name="weekly_lesson" value="{1}" />
<label for="{1}">{1}</label>
</div>
</div>
</div>
</script>

Iterate matching elements to control custom slick carousels

I am using slick carousel with some custom code to provide pagination. It's working great but now I want to have multiple carousels per page and although I've found solutions, I'm having trouble getting them to work with the customisations in my code.
There is an example [here] (Multiple Slick Sliders Issue) that iterates over all elements with a particular class and assigns an ID, but I just can't get it working with the custom pagination code I have.
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
let total = $('.carousel .item').length;
var first = $('.slick-active:first > div:first').get(0);
var last = $('.slick-active:last > div:last').get(0);
if($(last).html() == '')
last = $('.slick-active:last > div:not(:empty)').get(0);
let start,end;
$('.slick-slide > div').each(function(i,v){
if(first === $(v).get(0)) {
start = i+1;
}
if(last === $(v).get(0)) {
end = i+1;
}
});
$('.results').html(`Showing ${start} to ${end} of ${total} results`)
})
$('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $('.prev'),
nextArrow: $('.next')
})
.item {
background: silver;
color: black;
text-align: center;
font-size: 30px;
display: inline;
border: 5px solid white;
}
.nav {
width: 100%;
}
.nav p{
width: 50%;
float: left;
display: block;
text-align: center;
}
.results {
text-align: center;
width: 100%;
padding-top: 10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js"></script>
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
<div class="item">16</div>
<div class="item">17</div>
<div class="item">18</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
You could create a wrapper container to isolate instances
<div class="slider">
<div class="carousel">
<div class="item">1</div>
<div class="item">2</div>
</div>
<div class="nav">
<p class="prev">prev</p>
<p class="next">next</p>
</div>
<div class="results">
Showing 1 to 9 of [total] results
</div>
</div>
Then to initialize use an each loop for isolation
$('.slider').each(function() {
var $slider = $(this),
// arrows within this instance
$nArrow = $slider.find('.next'),
$pArrow = $slider.find('.prev');
// initialize this carousel instance with appropriate arrows
$slider.find('.carousel').slick({
rows: 2,
slidesToShow: 3,
slidesToScroll: 3,
autoplay: false,
arrows: true,
infinite: false,
draggable: false,
prevArrow: $pArrow,
nextArrow: $nArrow
});
})
For the events , look up to the container class and use find() for the elements within that instance
$('.carousel').on('init afterChange', function(event, slick, currentSlide){
var $slider = $(this).parent();
// examples finding elements within this instance
let total = $slider.find('.carousel .item').length;
var first = $slider.find('.slick-active:first > div:first').get(0);
var last = $slider.find('.slick-active:last > div:last').get(0);
// use find for other elements also
......
})

VueJS - input file repeater

I want delete item from array but there are the same item and js delete last one !
let app = new Vue({
el: '#app',
data: {
items: []
},
methods: {
addItem() {
this.items.push('');
},
removeItem(index) {
this.items.splice(index, 1);
}
}
});
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
<div id="app">
<ul class="list-group">
<li class="list-group-item" v-for="(item , index) in items">
remove
<input name="form[]" type='file'>
</li>
</ul>
<button #click='addItem'>new item</button>
</div>
JSFiddle: https://jsfiddle.net/6hvbqju2/
Vue uses an "in-place patch strategy" when dealing with list of elements. This strategy is not suitable when relying on form input values.
When using v-for directive it is better to define a v-bind:key to give Vue a hint to track each node.
We'll store numbers in the items array and use them as a key. In your case you should use an item's property that can serve as a unique key.
let app = new Vue({
el: '#app',
data: {
counter: 0,
items: []
},
methods: {
addItem() {
this.items.push(this.counter++);
},
removeItem(index) {
this.items.splice(index, 1);
}
}
});
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
<div id="app">
<ul class="list-group">
<li class="list-group-item" v-for="(item , index) in items" :key="item">
remove
<input name="form[]" type='file'>
</li>
</ul>
<button #click='addItem'>new item</button>
</div>
Your codes working fine but,
This is because of file input auto complete behaviour
See this example
let app = new Vue({
el : '#app',
data : {
items: [],
},
methods : {
addItem() {
this.items.push({file: null});
console.log(this.items)
},
removeItem(index) {
this.items.splice(index,1);
},
handleChange(item, event){
item.file = event.target.files["0"];
}
}
});
.upload-btn-wrapper {
position: relative;
overflow: hidden;
display: inline-block;
vertical-align: middle;
}
.btn {
border: 1px solid gray;
color: gray;
background-color: white;
padding: 4px 10px;
border-radius: 4px;
font-size: 15px;
font-weight: bold;
}
.upload-btn-wrapper input[type=file] {
font-size: 100px;
position: absolute;
left: 0;
top: 0;
opacity: 0;
}
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
<div id="app">
<ul class="list-group">
<li class="list-group-item" v-for="(item , index) in items">
remove
<div type="button" class="upload-btn-wrapper">
<button class="btn">{{ item.file ? item.file.name : 'Choose File' }}</button>
<input name="form[]" type="file" #change="handleChange(item, $event)">
</div>
</li>
</ul>
<button #click='addItem'>new item</button>
</div>

Partial html view's controller not working in Directive TemplateUrl using KendoPanelBar contenturl

Directive
app.directive('PanelbarDirective', function ($http) {
return {
restrict: "EA",
templateUrl: 'ngview/shared/panelbar.html'
};
});
testcontroller.js
'use strict';
app.controller('testcontroller', ['$scope',
function testcontroller($scope) {
$scope.LabelValue = 'From Controller';
}]);
panelbar.html
<div id="selected-values" class="col-sm-12 colSlctdValues" >
<ul id="panelbar"></ul>
<script>
$("#panelbar").kendoPanelBar({
dataSource: [
{
text: "Teachers",
expanded: true,
contentUrl: "ngview/shared/Teachers.html"
}
]
});
</script>
</div>
Teachers.html
<table ng-controller="testcontroller">
<body>
<tr>
<td>{{LabelValue}}</td>
</tr>
</body>
</table>
What problem i am facing is, it is always displaying value {{LabelValue}} instead of what i have assigned value to LabelValue in controller of partial view.
It has only issue when i try to implement this using javascript in
panelbar.html
<script>
$("#panelbar").kendoPanelBar({
dataSource: [
{
text: "Teachers",
expanded: true,
contentUrl: "ngview/shared/Teachers.html"
}
]
});
</script>
however i fixed this using
<ul id="panelbar" kendo-panel-bar k-options="panelBarOptions">
<li>
Teachers
<ul>
<li ng-include="'ngview/shared/Teachers.html'"></li>
</ul>
</li>
</ul>
Would love to know if anyone still can help me to do using script instead of ul and ng-include.
Thanks,
see this kendo official page examples
<div id="example">
<div class="wrapper">
<ul id="panelbar">
<li>
BODY
<div></div>
</li>
<li>
ENGINE
<div></div>
</li>
<li>
TRANSMISSION
<div></div>
</li>
<li>
PERFORMANCE
<div></div>
</li>
</ul>
</div>
</div>
<script>
$(document).ready(function() {
$("#panelbar").kendoPanelBar({
expandMode: "single",
contentUrls: [
'../content/web/panelbar/ajax/ajaxContent1.html',
'../content/web/panelbar/ajax/ajaxContent2.html',
'../content/web/panelbar/ajax/ajaxContent3.html',
'../content/web/panelbar/ajax/ajaxContent4.html'
]
});
});
</script>
<style>
.wrapper {
height: 320px;
margin: 20px auto;
padding: 20px 0 0;
background: url('../content/web/panelbar/astonmartin.png') no-repeat center 50px transparent;
}
#panelbar {
width: 250px;
float: right;
margin-bottom: 20px;
}
#panelbar p {
padding: 1em;
}
</style>
This part of code is copy-pasted of link content from KendoUI page in case that link change

Categories