Windows 8 Javascript: Listview invoke trouble - javascript

I've been struggling between using C# and Html to make a windows 8 app. But I decided to use Html because of certain functions. But I've been having trouble getting which Listview Item/Element/Child is selected if any. This is what I have in my Html:
<div id="shapeListItem" data-win-control="WinJS.Binding.Template" style="display: none;">
<div style="width: 100px; height: 100px;">
<img src="#" style="width: 100px; height: 100px;" data-win-bind="src: picture" />
</div>
</div>
<div id="shapes" data-win-control="WinJS.UI.ListView" data-win-options="{itemDataSource : shapeTemplate.itemList.dataSource,
itemTemplate: select('#shapeListItem'),
tapBehavior: 'toggleSelect',
selectionMode: 'single'}">
</div>
And my Javascript:
WinJS.Utilities.ready(function () { init(); });
function init() {
var shapes = document.getElementById("shapes").winControl;
//shapes.selected ???
}
I don't remember what all I've tried but I never got it to work.
I just want to get which item is selected and get the image uri from it. Or I could add another title or something to my data bindings, which appears to be working fine by the way. Thanks for looking at what I've got, if you have any other suggestions or methods for anything else it would be appreciated. Or if I need to post more code I'll do that.
Thanks again,
Stephen
EDIT:
Ohh I've also tried adding a "onitemInvoke : 'handler'" but that came up with an error.

Documentation: http://msdn.microsoft.com/en-us/library/windows/apps/br211852.aspx
Try:
function init() {
var shapes = document.getElementById("shapes").winControl;
// gets an array of the indices:
var selectedIndices = shapes.selection.getIndices();
}
A trick I have for you is to do:
function init() {
var shapes = document.getElementById("shapes").winControl;
debugger;
// gets an array of the indices:
var selectedIndices = shapes.selection.getIndices();
}
Then add "shapes" to the watch window - You will be able to see the APIs.

Related

jquery show() not displaying properly for highcharts graph

So i'm trying to display 3 graphs in the same div, toggled by buttons which show/hide the other divs respectively. I've set the other 2 graphs to
style= "display: none"
To ensure only one graph is shown upon load. This is how the default view looks like:
The default view is the day on day button. However, when I click the other 2 buttons, the width of the graph screws up, and it displays like this.
It shrinks for some reason. I have switched the order of display, and it's always the hidden graphs which have the size problem. I suspect it has something to do with the inline style property, but I cant figure out how to make it show properly.
Code snippet for graph:
<button onclick="showDay('tasks')">Day on Day</button>
<button onclick="showWeek('tasks')">Week on Week</button>
<button onclick="showMonth('tasks')">Month on Month</button>
<div class="portlet-body">
<div id="tasks"></div>
<div id="tasksWeek" style="display: none"></div>
<div id="tasksMonth" style="display: none"></div>
</div>
<script>
new Highcharts.StockChart({{masterDic['tasks']|safe}});
new Highcharts.StockChart({{masterDic['tasksWeek']|safe}});
new Highcharts.StockChart({{masterDic['tasksMonth']|safe}});
</script>
code snippet for calling (hackish right now)
<script>
function showDay(id) {
var idDay = "#"+id;
var idWeek = "#"+id+"Week";
var idMonth = "#"+id + "Month";
$(idWeek).hide(10);
$(idMonth).hide(10);
$(idDay).show(10);
}
function showWeek(id) {
var idDay = "#"+id;
var idWeek = "#"+id+"Week";
var idMonth = "#"+id + "Month";
$(idMonth).hide(10);
$(idDay).hide(10);
$(idWeek).show(10);
}
function showMonth(id) {
var idDay = "#"+id;
var idWeek = "#"+id+"Week";
var idMonth = "#"+id + "Month";
$(idDay).hide(10);
$(idWeek).hide(10);
$(idMonth).show(10);
}
</script>
Anyone have any ideas on how to fix this? Thanks alot! :)
EDIT:
css for portlet body (entire trace when using inspect element):
https://jsfiddle.net/ovnrpnb5/
setTimeout(function(){
$(window).resize();
})
Call this after show()
Figured it out if anyone's interested. Tldr: call reflow() on the chart after showing.
I was using hide() and show() instead of tabs as per #Grzegorz BlachliƄski's comment, so the solution given wasn't working.
I found this link which showed you how to access the element within your HTML http://ahumbleopinion.com/highcharts-tips-accessing-chart-object-from-container-id/
I was using the highcharts CDN, which apparently isnt 3.0.1, so the jquery method wasnt working. Hence, i made the following function and called it after every show()
// HACK TO GET IT TO DISPLAY PROPERLY
function callReflow(id){
var index = $(id).data('highchartsChart');
var chart = Highcharts.charts[index];
chart.reflow();
}
Worked like a charm :)

Copying element's style width attribute to another element

I have a progress bar that is outputted from a webapp program like this:
<div id="diskUsageProgressBar">
<div class="green-bar" style=" width: 1%;">
</div>
</div>
And I have added to the page a much nicer bar like this:
<div class="progress xs">
<div class="progress-bar progress-bar-red diskusgbar" style="width: 1%;"></div>
</div>
How could I use javascript (or JQuery) to copy the width value from the first one and paste it into the second one on page load?
Thanks for the help!
jQuery javascript:
$('.progress.xss .diskusgbar').css('width',
$('#diskUsageProgressBar .green-bar').css('width')
);
Like this:
$(function(){
$('.progress-bar-red').attr('style',$('.green-bar').attr('style'));
})
If you want to only copy the width then you can use native .width() method of jquery to get/set value:
$('.progress-bar').width($('.green-bar').width());
use this
$('.progress-bar').width($('.green-bar').width());
First, as said in Is it possible to listen to a "style change" event?
(function() {
var ev = new $.Event('style'),
orig = $.fn.css;
$.fn.css = function() {
orig.apply(this, arguments);
$(this).trigger(ev);
}
})();
And then bind it:
$('#diskUsageProgressBar > .green-bar').bind('style', function(e) {
$('.progress.xs > .diskusgbar').css('width',
$('#diskUsageProgressBar > .green-bar').css('width')
);
});
Hope it works. Maybe tricky and not so symple if the first bar is in another iframe.

Show div only if specific other divs have been clicked

I am new to jQuery (this is my second attempt). I looked for answers via Google and StackOverflow and I have tried quite a few but have yet to figure out the last part of my problem. Any help or guidance is most appreciated.
What I want to do is have a bunch of images(apple, pumpkin, candle, etc) that when clicked, fade the image out and then cross off the image's name in a text list. Then, if you click on specific sets of those images they will show a div containing a deal.
An example: If you click on the images of apple, pear and pumpkin (in any order) a deal will show.
Another example: You click on the images of candle, apple, pumpkin and key(in any order) a deal will show.
Another example: You click on all image items(in any order) a deal shows.
I have the first part working (click on an image, it fades out and crosses its name off the list).
What I need help with is checking to see if certain combinations of images have been clicked and if so show the deal div.
I was thinking I could use index for this but I haven't been able to make it work. Maybe there is a better way? Thanks for any guidance.
Here is my test code so far (JSFIDDLE):
HTML
<div class="pic1">
<img width="50" height="50" src="http://us.123rf.com/400wm/400/400/chudtsankov/chudtsankov1208/chudtsankov120800002/14670247-cartoon-red-apple.jpg" />
</div>
</div>
<div class="pic2">
<img width="50" height="50" src="http://www.in.gov/visitindiana/blog/wp-content/uploads/2009/09/pumpkin.gif" />
</div>
<div class="pic3">
<img width="50" height="50" src="http://upload.wikimedia.org/wikipedia/commons/f/fc/Candle_icon.png" />
</div>
<div class="pic4">
<img width="50" height="50" src="http://tasty-dishes.com/data_images/encyclopedia/pear/pear-06.jpg" />
</div>
<div class="pic5">
<img width="50" height="50" src="http://free.clipartof.com/57-Free-Cartoon-Gray-Field-Mouse-Clipart-Illustration.jpg" />
</div>
<div class="pic6">
<img width="50" height="50" src="http://images.wisegeek.com/brass-key.jpg" />
</div>
<div id="items">
<p class="apple">Apple</p>
<p class="pumpkin">Pumpkin</p>
<p class="candle">Candle</p>
<p class="pear">Pear</p>
<p class="mouse">Mouse</p>
<p class="key">Key</p>
</div>
<div class="someText">Reveal Deal #1 after finding apple, candle and mouse</div>
<div class="deal1">This is deal box #1! You must have found apple, candle and mouse! WIN</div>
<div class="someText">Reveal Deal #2 after finding key, pumpkin, pear and mouse!</div>
<div class="deal2">This is deal box #2! You must have found key, pumpkin, pear and mouse!</div>
<div class="someText">Reveal Deal #3 after finding ALL objects!</div>
<div class="deal3">This is deal box #3! You must have ALL the items!</div>
<div id="output"></div>`
CSS
.intro, .someText {
color:#333;
font-size:16px;
font-weight: bold;
}
.deal1, .deal2, .deal3 {
font-size: 18px;
color: red;
}
Javascript: jQuery
$(document).ready(function () {
$('.deal1, .deal2, .deal3').hide();
$('.pic1').click(function () {
$(this).data('clicked');
$('#items p.apple').wrap('<strike>');
$(".pic1").fadeOut("slow");
});
$('.pic2').click(function () {
$(this).data('clicked');
$("#items p.pumpkin").wrap("<strike>");
$(".pic2").fadeOut("slow");
});
$('.pic3').click(function () {
$(this).data('clicked');
$("#items p.candle").wrap("<strike>");
$(".pic3").fadeOut("slow");
});
$('.pic4').click(function () {
$(this).data('clicked');
$("#items p.pear").wrap("<strike>");
$(".pic4").fadeOut("slow");
});
$('.pic5').click(function () {
$(this).data('clicked');
$("#items p.mouse").wrap("<strike>");
$(".pic5").fadeOut("slow");
});
$('.pic6').click(function () {
$(this).data('clicked');
$("#items p.key").wrap("<strike>");
$(".pic6").fadeOut("slow");
});
$(document).on('click', '*', function (e) {
e.stopPropagation();
var tag = this.tagName;
var index = $(tag).index(this); // doesn't work, as it gives the total no. elements
$('#output').html(index);
});
});
first of all you can give your divs a corresponding data value to their p items for instance if you implement your div ( and all the other divs)
<div class="pic" data="pumpkin">
instead of
<div class="pic2">
You can write an almost oneliner with jquery
$('.pic').click(function () {
$("#items p."+$(this).attr("data")).wrap("<strike>");
$(this).fadeOut("slow");
});
you can define your sets:
set1 = ["apple","pumpkin"]
and after every click you can check clicked paragraphes with
$(document).ready(function () {
var set1 = ["apple", "candle", "mouse"]
$('.deal1, .deal2, .deal3').hide();
$('.pic').click(function () {
$("#items p." + $(this).attr("data")).wrap("<strike>").addClass("strike");
$(this).fadeOut("slow");
//test for set1
set1Completed = true;
for (i = 0; i < set1.length; i++) {
if ($("p.strike." + set1[i]).length==0) {
set1Completed = false;
break;
}
}
if (set1Completed) {
$('div.deal1').fadeIn(); // or fadeIn whatever u want
}
});
Create a custom event:
$('.HiddenItem').css({display:'none'}).on('somethingElseClicked',function(){
$(this).show();
});
And then trigger it with the other click:
$('.ItemToTrigger').on('click',function(e){
$('.HiddenItem').trigger('somethingElseClicked');
});
This is obviously supergeneralized, but it gives the framework necessary to trigger the event you want.
EDIT
Alright, so you will need to store each value for the clicks needed, as well as the total needed. I always prefer to use object-based variables rather than globals, so:
var click = {
deal1:[0,2],
deal2:[0,3],
deal3:[0,5]
}
This creates arrays for each deal, the first being the number of clicks that have happened and the second being the total needed minus 1. You will then increment the "clicks that have happened" value, as well as prevent it from allowing double-clicks, by the JS described later. First, I recommend adding a generic class to all clickable items, as well as the deal items they are associated with, and verifying that way. The HTML:
<div class="picItem d1" data-fruit="apple">
<div class="picItem d2" data-fruit="pumpkin">
<div class="picItem d1" data-fruit="candle">
<div class="picItem d2" data-fruit="pear">
<div class="picItem d1 d2" data-fruit="mouse">
<div class="picItem d2" data-fruit="key">
And the JS I described:
$('.picItem').on('click',function(){
var $this = $(this),
$fruit = $this.data('fruit');
$this.fadeOut('slow');
if($this.hasClass('d1') && !$this.hasClass('clicked1')){
if(click.deal1[0] < click.deal1[1]){
click.deal1[0]++;
$this.addClass('clicked1');
} else {
$('.deal1').trigger('showDeal');
}
}
if($this.hasClass('d2') && !$this.hasClass('clicked2')){
if(click.deal2[0] < click.deal2[1]){
click.deal2[0]++;
$this.addClass('clicked2');
} else {
$('.deal2').trigger('showDeal');
}
}
if(!$this.hasClass('clicked3')){
if(click.deal3[0] < click.deal3[1]){
click.deal3[0]++;
$this.addClass('clicked3');
} else {
$('.deal3').trigger('showDeal');
}
}
$('.'+$fruit).wrap("<strike>");
});
The last if is for all elements clicked, hence not the need for adding a class and checking. The final piece grabs the associated data attribute and strikes it out.
Now you just trigger the event:
$('.deal1,.deal2,.deal3').on('showDeal',function(){
$(this).show();
});
This event will only be triggered when the appropriate number of clicks has been reached. Here is the jsFiddle you gave me updated to show it is working as requested.
If you want to only allow one deal, you would just turn off the event after being triggered:
var $allDeals = $('.deal1,.deal2,.deal3');
$allDeals.on('showDeal',function(){
$(this).show();
if($(this).hasClass('deal3')){
// this is to prevent deal 1 and deal 2 showing, since the criteria for them is also met
$allDeals.not('.deal3').hide();
}
// this turns off all other deals
$allDeals.off('showDeal');
$('.picItem').off('click');
});
Not sure if you would need it or not, figured I would include it just in case. Here is an updated jsFiddle to show that case working.

How to implement multiple tinyscrollbars from a class?

I'm trying to implement multiple scrollbars with the plugin Tinyscrollabr.js
http://baijs.nl/tinyscrollbar/
To implement the scrollbars, i use a function scrollify like in this article :
http://www.eccesignum.org/blog/making-tinyscrollbarjs-easier-to-implement
HTML :
<ul id="myList">
<li id="scrollbar1" class="col">
<h2>Title 01</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
<li id="scrollbar2 class="col">
<h2>Title 02</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
<li id="scrollbar3 class="col">
<h2>Title 03</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
</ul>
Javascript :
function scrollify(element,options) { // '#element', {list:of,key:values}
var opt = options || {}
$(element).children().wrapAll('<div class="viewport"><div class="overview"></div></div>');
$(element).prepend('<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>');
$(element).tinyscrollbar(options);}
$scrollbar1 = $('#scrollbar1 .scrollBox') ;
$scrollbar2 = $('#scrollbar2 .scrollBox');
$scrollbar3 = $('#scrollbar3 .scrollBox');
$scrollbar4 = $('#scrollbar4 .scrollBox');
$(function() {
scrollify($scrollbar1);
scrollify($scrollbar2);
scrollify($scrollbar3);
scrollify($scrollbar4);
})
I would to make this more simple.
For example, i would to be able to make this :
$(function() {
scrollify('.scrollBox');
})
But tinyscrollbar need an id. With a class, it's load the first scrollbar and not the others. Firebug return this error message "f.obj[0] is undefined"
Sorry if my question is stupid, but how can I do for applying tinyscrollbar to a list of elements with a class ?
And then, after some actions how to update all this scrollbars with the function $allScrollbars.tinyscrollbar_update();
Thanks for help, I'm just beginning with javascript and i'm trying to learn.
I would count the number of elements with the class:
var scrollCount = $(".scrollbox").size();
Then use an iterating loop to call each of your IDs:
for (i=0; i<5; i++) {
scrollify($('#scrollbar' + i));
}
Also I would recommend using DIVs instead of the list setup you have, use the example from the link you shared as a starting point :)
Thanks KneeSkrap3r for your answer. It's a good solution to make this but i'm trying to do something in the case i' don't know the numbers of element to scroll.
I think I've found with something like this (it's a part from the first jquery plugin i'm trying to do ) where $el is all elemnts with the class"scrollbox".
$el.each(function(index)
{
var $scrolls = $(this);
function scrollify(element,options)
{ // '#element', {list:of,key:values}
var opt = options || {}
$(element).children().wrapAll('<div class="viewport"><div class="overview"></div></div>');
$(element).prepend('<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>');
$(element).tinyscrollbar(options);
}
scrollify($scrolls);
// Update heights
$(window).resize(function()
{ $scrolls.tinyscrollbar_update('relative');
});
})
Like this, it's seems to work but i don't know if i'm using good practice of javascript.
For the Html markup, I told the li elements for div, it's better for the semantic.
Thanks for tips ;-)

Handle HTML code block as an object?

I have a div that basically represents a book (so a nice div layout with an image of the book, title, price, red background if on sale etc.). So what i do is to get the properties of a book from the database, insert the values in kind of an html template and display it.
Now, once it is displayed i hate how i have to handle the data. I have to either parse css properties to figure out if a book is on sale for an example or i have to keep the data in another place as well (some javascript array or use the jquery data feature). The first option is ugly the second one would require me to update two things when one property changes - which is ugly as well.
So what i would like is to handle that block of html (that represents a single book) as an object. Where i can call obj.setPrice(30); and things like that and finally call obj.update(); so it would update its appearance.
Is there anyway to accomplish this ? Or something like this ? I just feel that once i render the data as html i loose control over it :(
Suppose your html div is like this
<div id="book1">
<div id="price">$30</div>
...
</div>
You can define a Book object as follows:
var Book = function(name) {
this.name = name;
}
Book.prototype = {
setPrice : function(price) {
this.price = price;
},
update : function() {
pricediv = document.getElementById(this.name)
pricediv.innerHTML = '$'+price;
}
}
var book = new Book('book1')
book.setPrice(50);
book.update();
I guess your best shot is write your own object / methods for that.
var Book = function(){
var price = args.price || 0,
color = args.color || 'red',
height = args.height || '200px',
width = args.width || '600px',
template = "<div style='background-color: COLOR; width=WIDTH; height: HEIGHT;'><span>$PRICE</span><br/></div>";
return {
setPrice: function(np){
price = np;
return this;
},
setColor: function(nc){
color = nc;
return this;
},
setHeight: function(nh){
height = nh;
return this;
},
render: function(){
template = template.replace(/COLOR/, color);
template = template.replace(/PRICE/, price);
// etc
// use jQuery or native javascript to form and append your html
$(template).appendTo(document.body);
}
};
};
This is just a pretty basic example which can be optimized like a lot. You may even think about using John Resigs microtemplate (http://ejohn.org/blog/javascript-micro-templating/)
Usage from the above example would look like:
var book = Book({
price: 30,
color: 'blue'
});
book.render();
To change values:
book.setPrice(140).setColor('yellow').setHeight('500').render();
I have been playing around with Microsoft's proposal for jQuery Templates and Data Linking and so far it's going awesome.
TLDR, checkout this demo.
It's extremely easy to just link up a piece of HTML with a JavaScript object and from thereon, only update the JavaScript object and the HTML updates automatically.
Here's a simple example. Create the HTML that will represent your widget.
<div class="book">
<img width="100" height="100" src="" />
<div class="title"></div>
<div class="price"></div>
</div>
Then create a JavaScript object and dynamically link it to the HTML above. Here is a sample object:
var book = {
title: "Alice in Wonderland",
price: 24.99,
onSale: true,
image: "http://bit.ly/cavCXS"
};
Now onto the actual linking part. The items we are going to link up are:
A data-onsale attribute in the outer div which will be either "true" or "false"
The image src attribute to the image property of our book
title div to the title property
price div to the price property
The following sets up the linking. Note that we are only doing a one way linking here, but it's possible to setup a two way linking also using the linkBoth function.
$(book)
.linkTo('title', '.title', 'html')
.linkTo('price', '.price', 'html')
.linkTo('image', '.book img', 'src')
.linkTo('onSale', '.book', 'data-onsale')
That's it. From now onwards, just update the book object and the HTML will automatically update. Update the properties of the book like you would update html attributes using the attr function.
$(book).attr({
price: 14.75
});
or
$(book).attr('price', 14.75);
The code above is only using Data Linking, but the proposal also mentions combining data linking with templates which would make this even more easier. From what I reckon, you would be able to do this and get the above functionality:
<script id="bookTemplate" type="text/html">
<div class="book" data-onsale="{{link onSale }}">
<img width="100" height="100" src="{{link image }}" />
<div class="title">{{link title }}</div>
<div class="price">{{link price }}</div>
</div>
</script>
Link the above template with the book object in one step and add it to the page:
$('#bookTemplate').render(book).appendTo('body')
Update the properties of the book object, and changes will reflect.

Categories

Resources