How to separate Kendo Tabstrip tab list and content divs in html? - kendo-ui

So, I'm working with kendo in js. I'd like to use the tabstrip, but I'd like the tabs to be contained in a header that is styled and contains some other elements, so I am wondering if there is a way to separate the tab list and their associated divs. I'm looking to have something like this:
<div class="border">
<div class="header">
<div id="tabstriplist">
<ul>
<li id="tab1">First tab</li>
<li id="tab2">Second tab</li>
</ul>
</div>
<div>Some other text</div>
</div>
<div class="content">
<div id="tabcontent1">Stuff</div>
<div id="tabcontent2">Stuff</div>
</div>
</div>
However, it seems like all the example code I can find simply puts the associated divs immediately after the list, so the order of the divs corresponds to the list order. Is there any way to accomplish this sort of thing?
Edit: to clarify, I am looking for a way to display the tabcontent divs outside of the header. I don't really care about where the actual divs are in the html, but rather, where they will appear when they are generated on the page.

Ok, I figured it out. I don't think there is a way to directly attach the content divs to the tabs, but you can achieve the same functionality with the "show" or "select" events for the tabstrip. Here's what I ended up writing, boiled down.
Html:
<div class="border">
<div class="header">
<div id="tabstriplist">
<ul>
<li id="tab1">First tab</li>
<li id="tab2">Second tab</li>
</ul>
<div></div>
<div></div>
</div>
<div>Some other text</div>
</div>
<div class="content">
<div id="tabcontent1">Stuff1</div>
<div id="tabcontent2">Stuff2</div>
</div>
</div>
Js:
$(document).ready(function () {
function onTabSelect(selection) {
var contents = $("#content").children();
var tabNum = selection.contentElement.id.charAt(selection.contentElement.id.length - 1);
for (i = 0; i < contents.length; i++) {
if (tabNum - 1 === i) {
$("#" + contents[i].id).show();
}
else {
$("#" + contents[i].id).hide();
}
}
}
$("#tabstrip").kendoTabStrip({
show: onTabSelect
}).data("kendoTabStrip").select(0);
$("#tabstrip-1").remove();
$("#tabstrip-2").remove();

First solution would be to leave empty divs like:
<div class="border">
<div class="header">
<div id="tabstriplist">
<ul>
<li id="tab1">First tab</li>
<li id="tab2">Second tab</li>
</ul>
<div></div>
<div></div>
</div>
<div>Some other text</div>
</div>
<div class="content">
<div id="tabcontent1">Stuff</div>
<div id="tabcontent2">Stuff</div>
</div>
</div>
And then set tab content whenever you want
$(document).ready(function() {
var tabstrip = $("#tabstriplist").kendoTabStrip().data("kendoTabStrip");
var item = tabstrip.contentElement(0);
//replace the first tab content
$(item).html($("#tabcontent1").html());
});
Or to create the entire tab strip dinamically using:
<div id="tabstrip"></div>
<div class="content">
<div id="tabcontent1">Stuff</div>
<div id="tabcontent2">Stuff2</div>
</div>
And JS to initialize like:
var tabstrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
tabstrip.append({
text: "Firts tab",
content: $("#tabcontent1").html()
});
tabstrip.append({
text: "Second tab",
content: $("#tabcontent2").html()
});

Related

Collapse using Transition Vue

I would like to use Vue's collapse in my code, but I have an error.
[Vue warn]: <transition-group> children must be keyed: <p>
My component:
<template xmlns:v-model="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<section style="background-color: #dedede;">
<div class="container-fluid">
<div class="Consult-faq container">
<div class="row">
<div class="col-sm-12">
<h2>Cursos</h2>
<a v-for="(course,id) in courses" v-on:click="course.show = !course.show">
<a v-on:click="show = !show">
<div class="col-xs-12" style="border-bottom: solid;border-bottom-color: #999999;border-bottom-width:1px ">
<div class="col-xs-12">
<h4>
<i v-if="course.show" class="fa fa-plus-square text-right" aria-hidden="true"/>
<i v-else class="fa fa-minus-square text-right" aria-hidden="true"/>
{{course.text}}
</h4>
</div>
</div>
<transition-group name="fade">
<p v-if="show">
<div class="col-xs-12">
<article v-for="n in 2" class="Module-content">
<div class=" col-sm-12 col-md-6" style="position: relative;">
<div v-for="(course, index) in course.courses">
<course-card v-if="index % 2 == n - 1" :course="course"></course-card>
</div>
</div>
</article>
</div>
</p>
</transition-group>
</a>
</a>
</div>
</div>
</div>
</div>
</section>
</template>
<script>
export default{
props : [
'courses'
],
data(){
return {
show: false
}
},
mounted() {
console.log(this.courses)
}
}
</script>
So, I'd like to know to collapse item per item. Like this in image.
When I click to expand, all courses expand or close all courses close.
Transition is irrelevant here (though you can get rid of that warning by using transition instead of transition-group, because the transition is only acting on a single node, not a group.)
Right now you're depending on a single variable show to control all of the elements' visibility, so they will all respond to clicks on any of them:
<a v-on:click="show = !show">
<p v-if="show" >
You need individual variables for each element if you want them to expand/collapse separately. You partially did this already, just change the remaining instances of show with course.show and you should be good to go.
(Probably want to clean up that nested <a> within <a> while you're at it; you can just remove the inner one.)
I solved this using vue-resource, I was using Guzzle in Laravel and require data in Controller make this not reactive. And I solved this problem using vue-resource in component.

Javascript to sort elements

I've need to sort some items on the page where the CMS I use doesn't provide for this. I can add some tags dynamically, but I need help here with some Javascript that would put the items in the correct order.
Further at the top of the HTML page I've got an 'event selector', e.g.:
<div class="w-embed">
<div event-selector="weddings"></div>
</div>
This would determine which set of the sorting numbers to use. Each item includes some code with a sort number from each set. w-dyn-item are the elements that need sorting.
<div class="w-dyn-list">
<div class="w-dyn-items">
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="09"></div>
<div sort-event="exhibition" sort="110"></div>
<div sort-event="wedding" sort="2"></div>
</div>
<div>
Content A
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="06"></div>
<div sort-event="exhibition" sort="60"></div>
<div sort-event="wedding" sort="1"></div>
</div>
<div>
Content B
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="01"></div>
<div sort-event="exhibition" sort="54"></div>
<div sort-event="wedding" sort="3"></div>
</div>
<div>
Content C
</div>
</div>
</div>
</div>
The logic would be: Sort w-dyn-item elements by using the 'sort-event' numbers that correspond to the 'event-selector' (from smallest to largest number).
The site's using jQuery if that's any help.
I've put it into a Fiddle here: https://jsfiddle.net/j2rqze8p
Many thanks for any help.
Here is how you can actually sort the elements with jQuery.
var sortPropertyName = $('.w-embed [event-selector]').attr('event-selector');
var sortAttrValues = {
'weddings': 'wedding',
'exhibitions': 'exhibition',
'conferences': 'conference'
};
var sortAttributeValue = sortAttrValues[sortPropertyName];
if(!sortAttributeValue) {
throw new Error('Unable to sort. Sort attribute value not found.')
}
var attrSelector = '[sort-event="' + sortAttributeValue + '"]';
var $container = $('.w-dyn-items');
var $items = $container.children('.w-dyn-item');
$items.sort(function (item1, item2) {
var item1Value = $(item1).find(attrSelector).attr('sort');
var item2Value = $(item2).find(attrSelector).attr('sort');
return parseInt(item1Value) - parseInt(item2Value);
});
$items.detach().appendTo($container);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="w-dyn-list">
<div class="w-embed">
<div event-selector="weddings"></div>
</div>
<div class="w-dyn-items">
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="09"></div>
<div sort-event="exhibition" sort="110"></div>
<div sort-event="wedding" sort="2"></div>
</div>
<div>
Content A
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="06"></div>
<div sort-event="exhibition" sort="60"></div>
<div sort-event="wedding" sort="1"></div>
</div>
<div>
Content B
</div>
</div>
<div class="w-dyn-item">
<div class="w-embed">
<div sort-event="conference" sort="01"></div>
<div sort-event="exhibition" sort="54"></div>
<div sort-event="wedding" sort="3"></div>
</div>
<div>
Content C
</div>
</div>
</div>
</div>
There are two moments.
First, as I noticed the value of event-selector is plural whereas sort-event are singular.
I solved this by having a hash to match one to another.
The another thing is that you might need to run this script on 'event-selector' change if you want the sort to by dynamic. But it's basically a matter of a different discussion.

Display data with an AngularJS ng-repeat, in a div, side by side

I have an arraylist from which I need to get values where isActive = true, and to display the data in a <div> tag with the use of ng-repeat.
My problem is that I don't want to keep using ng-repeat every time, while fetching values in each <div> tag.
Is there any generic solution which will iterate only once, and I can see the value in <div>, side by side. Please see this attempt:
enter link description here
I want to see a result like this:
You can write your ng-repeat like below.
Whenever it get isActive true, it will create the div section for this.
<body ng-controller="MainCtrl">
<div ng-repeat="tempData in data">
<div ng-if="tempData.isActive == true" >
<div class="col-xs-12" >
<div class="col-xs-4">Plan Type:</div>
<div class="col-xs-8">{{tempData.plantype}}</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">Term:</div>
<div class="col-xs-8">{{tempData.term}}</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">Rate:</div>
<div class="col-xs-8">{{tempData.rate}}</div>
</div>
</div>
</div>
</body>

WinJS Repeater Only Binding First Property

I have a list of objects with two properties, and I want my repeater to display each of them. The first property should be inside an <h2> tag, and the second should be in an <h3> tag.
HTML:
<div class="dataColumns" data-win-control="WinJS.UI.Repeater">
<h2 data-win-bind="textContent: Title"></h2>
<h3 data-win-bind="textContent: SomeOtherProperty"></h3>
</div>
JS:
var columnData = new WinJS.Binding.List([
{ Title: 'First Title', SomeOtherProperty: 'First SomeOtherProperty' },
{ Title: '2nd Title', SomeOtherProperty: '2nd SomeOtherProperty' }]);
document.querySelector('.dataColumns').winControl.data = columnData;
Here is the actual output, as seen in the DOM Explorer:
<div class="dataColumns win-repeater win-disposable" data-win-control="WinJS.UI.Repeater">
<h2 class="win-disposable">First Title</h2>
<h2 class="win-disposable">2nd Title</h2>
</div>
Why is only the <h2> shown for each item?
Here is what I would have expected:
<div class="dataColumns win-repeater win-disposable" data-win-control="WinJS.UI.Repeater">
<h2 class="win-disposable">First Title</h2>
<h3 class="win-disposable">First SomeOtherProperty</h3>
<h2 class="win-disposable">2nd Title</h2>
<h3 class="win-disposable">2nd SomeOtherProperty</h3>
</div>
A Repeater template may have only one direct descendant element (like in the case below, a single child div:
<div class="dataColumns" data-win-control="WinJS.UI.Repeater" >
<div>
<h2 data-win-bind="textContent: Title"></h2>
<h3 data-win-bind="textContent: SomeOtherProperty"></h3>
</div>
</div>
Results:
You may also consider using a WinJS.Binding.Template for the contents of the Repeater:
<div class="template" data-win-control="WinJS.Binding.Template">
<div>
<h2 data-win-bind="textContent: Title"></h2>
<h3 data-win-bind="textContent: SomeOtherProperty"></h3>
</div>
</div>
<div class="dataColumns" data-win-control="WinJS.UI.Repeater"
data-win-options="{template: select('.template')}">
</div>

Append to newly created div

I have a question to those jquery/ajax/javascript veterans, im creating a skill calculator for a certain game... everything is working fine up until this:
this is the ajax output:
{"skills":{"skill_id_1":"skill_name_1","skill_id_2":"skill_name_2"}}
this is my ajax:
function setOutput(){
if(httpObject.readyState == 4){
var results = eval('('+httpObject.responseText+')');
if (results['skills']){
$('#skilldiv').empty(); // empty div
$.each(results['skills'], function(key, value)
{
$("<div></div>").appendTo("#skilldiv").attr({class: "skilldesc"});
$("<div> </div>").appendTo(".skilldesc").attr({class: "skillinfo"});
$("<div> </div>").appendTo(".skilldesc").attr({class: "skilltxt"});
});
}
}
}
this is my div:
<div id="wrapper">
<ul>
<li id="skilldiv"></li>
</ul>
</div
so my problem is.. how can i append skillinfo & skilltxt to skilldesc which is just appended to skilldiv...
i tried this:
$.each(results['skills'], function(key, value)
{
$("<div></div>").appendTo("#skilldiv").attr({class: "skilldesc"});
$("<div> </div>").appendTo(".skilldesc").attr({class: "skillinfo"});
$("<div> </div>").appendTo(".skilldesc").attr({class: "skilltxt"});
});
but all results go into the first skilldesc,
im trying to get these:
<div id="wrapper">
<ul>
<li id="skilldiv">
<div class="skilldesc">
<div class="skillinfo">Some Info of skill 1 here</div>
<div class="skilltxt">Name of skill 1 here</div>
</div>
<div class="skilldesc">
<div class="skillinfo">Some Info of skill 2 here</div>
<div class="skilltxt">Name of skill 2 here</div>
</div>
</li>
</ul>
</div>
but i get this instead;
<div id="wrapper">
<ul>
<li id="skilldiv">
<div class="skilldesc">
<div class="skillinfo">Some Info of skill 1 here</div>
<div class="skilltxt">Name of skill 1 here</div>
<div class="skillinfo">Some Info of skill 2 here</div>
<div class="skilltxt">Name of skill 2 here</div>
</div>
<div class="skilldesc"></div>
</li>
</ul>
</div>
any help would be very much appreciated . . . thx
Because .skilldesc selects the first div too.
You can try this,
$.each(results['skills'], function(key, value)
{
$skilldesc = $("<div></div>").attr({class: "skilldesc"});
$("<div> </div>").appendTo($skilldesc).attr({class: "skillinfo"});
$("<div> </div>").appendTo($skilldesc).attr({class: "skilltxt"});
$skilldiv.appendTo("#skilldiv");
});
Also, you should to manipulations in objects in memory (not in dom).

Resources