Listview causes exception - windows universal app 8.1 - javascript

I have a list view to choose content from
<div id="mediumListIconTextTemplate"
data-win-control="WinJS.Binding.Template"
style="display: none">
<div class="mediumListIconTextItem">
<img class="mediumListIconTextItem-Image" src="img/tegan.jpg" />
<div class="mediumListIconTextItem-Detail">
<h4 data-win-bind="innerText: title"></h4>
<h6 data-win-bind="innerText: text"></h6>
</div>
</div>
</div>
<div id="groupedListView" style="display:none;"
data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, tapBehavior: 'toggleSelect',
itemTemplate: select('#mediumListIconTextTemplate'),
groupDataSource: myData.groupedItemsList.groups.dataSource,
groupHeaderTemplate: select('#headerTemplate'),
layout: {type: WinJS.UI.GridLayout}}">
</div>
What i did is, i just made listview 'display:none' and on click add i just made 'display:block'. The code below
$("#groupedListView").css('display', 'block');
var name ='';
var myListView = document.getElementById("groupedListView").winControl;
myListView.forceLayout();
myListView.selection.clear();
myListView.addEventListener("iteminvoked", function (e) {
e.detail.itemPromise.then(function (invokedItem) {
name = invokedItem.data.picture; //name of selected data
alert(name + "\"s defined: " + num + ".", 'i');
$("#groupedListView").css('display', 'none'); //hide the listview
});
}, false);
Its works fine for one time, On 2nd, 3rd... list item selection it fails and shows exception
What is the best way to load listview and access the content..?
P.S: The whole listview and other functions are in single html page

Related

JS function Cant get the Value from vbhtml

How can I get value from my html action link, I tried to set the value in js function and it is work, and the problem is js not get the value form html file, and this forloop only the first one will call the Javascript function.
this is my js function
function selectTemplate() {
$('#choose').on('click', function () {
var objTemplate = $(".styTemplate").val();
$.post(strRoot + "/Home/Index/", { styTemplate: objTemplate });
});
};
and this is my vbhtml code
#For Each item In Model
Dim currentItem = item
'<!-- single-awesome-project start -->
#<div Class="col-md-4 col-sm-4 col-xs-12 #Html.DisplayFor(Function(modelItem) currentItem.strTemplateType)">
<div Class="single-awesome-project">
<div Class="awesome-img">
<img src="#Url.Content("~/Content/TemplateCSS/img/portfolio/" & currentItem.strTemplateType & ".jpg")" alt="" />
<div Class="add-actions text-center">
<div Class="project-dec">
<a Class="venobox" data-gall="myGallery" href="#Url.Content("~/Content/TemplateCSS/img/portfolio/" & currentItem.strTemplateType & ".jpg")">
<h4>#currentItem.strTemplateName</h4>
<span> Web Development</span>
#Html.ActionLink("Choose", "companyInfomation", "Home", New With {.id = "choose"}, New With {.styTemplate = currentItem.strTemplateName})
</a>
</div>
</div>
</div>
</div>
</div>
'<!-- single-awesome-project end -->
Next
</div>
<script>
selectTemplate();
</script>
Maybe it's better to use onclick attribute? Use this instead of Html.ActionLink:
Choose

in meteor how to stop functionalities to work at a time?

In meteor, I have created a cards dynamically after submitting the form. and the dynamic card contains the show and hide buttons. When I click on show option button the hidden part is showing for all the cards instead of that particular card. the problem is the card is creating dynamically so I thought that is problem .. how to make the functionality to work separately to the each card.
Here I am attaching the code:
<div id="newActionCard">
{{#each newaction}}
<div class="workflowcard">
<div class="module-card">
<div class="res-border"></div>
<div class="card-img"></div>
<div class="res-content">
<div class=" assigned-team">{{team}}</div>
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="description">{{description}}</div>
<div class=" due-on">Due on:{{d_date}}</div><hr>
<div class="subcontent">
{{> actioncardsubcontent}}
</div>
<div class="reqext">
{{> requestextensioncard}}
</div>
</div>
<div class="due">
Due on:
<div>
<span class="day-stamp">THU</span><br>
<div class="date-stamp">26</div>
<div class="month-stamp">AUG
</div>
</div>
</div>
</div>
<div class="btn-box newaction">
<button type="button" class="cancelsub" >New Action</button>
<button type="submit" class="createbtnsub" >Show Options</button>
</div>
<div class="btn-box showoption">
<button type="button" class="hideoption" style="display:none">Hide Options</button>
</div>
{{/each}}
</div>
In JS I have written the hide and show functionalities in the events..now how to stop functionality to all cards at a time.
Here is my JS:
Template.workflow.events({
"click .createbtnsub" : function() {
$( ".subcontent" ).show();
$('.createbtnsub').hide();
$('.cancelsub').hide();
$('.hideoption').show();
$('.requestextension').show();
},
"click .hideoption": function(){
$('.subcontent').hide();
},
"click .hideoption": function(){
$(".subcontent").hide();
$('.cancelsub').show();
$('.createbtnsub').show();
$('.requestextension').hide();
$('.hideoption').hide();
$('.reqext').hide();
},
"click #createActionBtn": function(){
$('#createAction').hide();
$('.editw').show();
$('.hidew').show();
},
});
Template.actioncardsubcontent.rendered = function(){
this.$(".subcontent").hide();
};
Template.requestextensioncard.rendered = function(){
this.$(".reqext").hide();
};
Template.workflow.helpers({
getWorkflow: function(){
return Workflow.find();
},
user: function(){
return Meteor.users.find({});
},
getNewaction: function(){
return Newaction.find();
},
});
Please see the following and adjust the selectors as needed:
"click .showoption": function(event){
$(event.currentTarget).next('button').show();
}
This will work for selecting sibling elements, however as a tip I would recommend rewriting your template.helper that returns the cards data from the database into something more specific.
Something like dynamic classes based on index or id so your class/id names would return as follows .showoption-12kjddfse4 . Then you can just get the attribute of the current target and apply it to your js selector.
Also as kind of an explination to why all buttons were showing, is you were using the class selector, which is meant for grabbing groups of elements/nodes. This is also another reason to created more specific classnames/ids to your use case.
So in your class name you could do something like
<button class="showoption" id="{{_id}}">button</button>
<button id="hiddenoption-{{_id}}" class="hiddenoption">button</button>
Then selecting your elements would be easier as follows:
'click .showoption'(event) => {
let id = event.currentTarget.getAttribute(id);
document.getElementById('hiddenoption-'+id).style.display = 'block';
}

Dynamically Populate JQUERY Mobile Multi-Page Page

JQUERY Mobile Beginner Question: I have two pages in my simple multi-page JQUERY Mobile 'App'. When the user navigates to PAGE2, I want to do an AJAX call to get a JSON object containing a list of people + DB ID pairs. I want to present the list of people as buttons on PAGE2.
Code Snippet:
<div id="PAGE2" data-role="page">
<div class="ui-content">
// I want buttons to appear sequentially here
</div>
</div>
PAGE2 is my "placeholder" to populate with:
<input type="button" id="id1" name="id1" value="Bob Smith"/>
<input type="button" id="id2" name="id2" value="Jane Doe"/>
<input type="button" id="id3" name="id3" value="Kayla Kaye"/>
I'd also need to add a 'click' event handler in the script to react to the buttons. The reaction will be the same for all buttons (dynamically populate a PAGE3 with people detail, but I think I can figure that out if I see how PAGE2 population is correctly handled). What is the proper way to go about dynamically "creating" PAGE2 using the skeleton in place?
if jquery is allowed:
var elements = { id1:'Bob Smith', id2:'Jane Doe', id3:'Kayla Kaye'};
$.each( elements, function( key, value ) {
$("#PAGE2 .ui-content").append('<input type="button" id="' + key + '" name=" + key " value " + value +'"/>');
}
You can try this
$('#PAGE2').on('pagebeforeshow', function(){
var people = [
{ name:'Bob Smith', age:'56', place:'London'},
{ name:'John', age:'65', place:'USA'},
];
var btns;
$.each(people,function(indx,ppl){
btns = btns + '<input type="button" name="id1" value="' + ppl.name +'"/>';
});
$('#content_div').html(btns);
});
set id to div content to content_div
Here is a DEMO
With your 3 pages setup like this (I have added container divs for the buttons and details):
<div data-role="page" id="PAGE1">
<div data-role="header">
<h1>PAGE 1</h1>
</div>
<div role="main" class="ui-content">
Go to page 2
</div>
</div>
<div data-role="page" id="PAGE2">
<div data-role="header">
<h1>PAGE 2</h1>
</div>
<div role="main" class="ui-content">
<div id="thePeople"></div>
</div>
</div>
<div data-role="page" id="PAGE3">
<div data-role="header">
<a data-rel="back" class="ui-btn ui-btn-icon-left ui-icon-back">Back </a>
<h1>PAGE 3</h1>
</div>
<div role="main" class="ui-content">
<div id="theDetails"></div>
</div>
</div>
You can use the pagecontainer widget's beforeshow event to make your ajax call:
http://api.jquerymobile.com/pagecontainer/#event-beforeshow
In my example, I am checking where you are coming from and where you are going to. So coming from PAGE1 to PAGE2, I make the AJAX call and create the buttons. But if returning from PAGE3 to PAGE2, I just leave the already created buttons alone. Ater adding the buttons to the page, make sure and call .enhanceWithin() on the container so that jQM enhances the buttons.
$(document).on( "pagecontainerbeforeshow", function( event, ui ) {
var prevID = ui.prevPage.prop("id");
var newID = ui.toPage.prop("id");
if (prevID == "PAGE1" && newID == "PAGE2") {
//we have come from page 1 to page 2, so make AJAX call and populate page 2
var data = [
{ "id": "id1", "name":'Bob Smith'},
{ "id": "id2", "name":'Jane Doe'},
{ "id": "id3", "name":'Kayla Kaye'},
];
var buttons = '';
$.each(data, function(indx){
buttons += '<input type="button" name="' + this.id + '" value="' + this.name +'"/>';
});
$("#thePeople").empty().append(buttons).enhanceWithin();
}
});
Finally, when PAGE2 is created, I use event delegation to create a click event for any buttons that might be added (with event delegation, the buttons don't have to exist at the time the event is bound). In the event, get the id/name for the button that is clicked, get the details (Another AJAX call?), populate PAGE3, and then navigate to PAGE3 using the pagecontainer widget change method:
http://api.jquerymobile.com/pagecontainer/#method-change
$(document).on("pagecreate","#PAGE2", function(){
$(document).on('click', '#thePeople input[type="button"]', function(e){
var personid = $(this).prop("id");
var name = $(this).val();
$("#theDetails").text('Details for ' + name);
$( ":mobile-pagecontainer" ).pagecontainer( "change", "#PAGE3", { transition: "slide" });
});
});
DEMO

jQuery pass dynamically created variable to another function

I have form partial in Rails, laid out like so:
<div class"row">
<div class="col-md-6" id="top_level">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category1">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category2">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category3">
</div>
</div>
<div class"row">
<div class="col-md-3" id="sub_category4">
</div>
</div>
<div class"row">
<div class="col-md-3" id="sub_category5">
</div>
</div>
It is for selecting categories and sub-categories of items.
listings_controller:
def new
#product_listing = Listing.new
#product_ = Product.find(params[:product_id])
# gon.categories = EbayCategory.all
gon.top_level = EbayCategory.top_level
end
In the model:
scope :top_level, -> { where('category_id = parent_id').order(:id) }
Each category record (17989 of them) has a unique category_id, and a parent_id. As indicated above, the top level category_id = the parent_id for the same record. All the subcategories have their own category_ids, which are the parent_ids of the next level down, and so on, varying between 1 and 5 sub-levels.
I've tried a cascade of view files, which works fine (it renders the correct categories and sub-categories) but I can't pass the listing id that way because I don't know how to transmit 2 ids (one for the parent category, one for the listing id) through the params hash using the link_to url helper, so I lose the id for the listing I'm trying to create while navigating all the sub-categories.
So I'm trying it with jQuery, using the Gon gem. Not only does this mean loading the entire db table (about 7 MB, once I un-comment the line for use in level 2 thru 5) into ram, but I can't figure out how to pass the category_id from the dynamically created top_level list when one of its elements is clicked. There are many levels to go, but right now I'm just trying to console.log the category_id for ONE level, so I can see that it's registering. So far unsuccessful, after trying many different syntaxes and methods, of which this is the latest:
<script type="text/javascript">
$(gon.top_level).each(function(){
$("#top_level").append('<h5>' + this.main_category + " >" + '</h5>').data($(this).category_id);
})
$("#top_level").on('click', 'a', function(){
console.log($(this).data());
});
</script>
...returns
Object {}
to the console.
Any suggestions on how to store ids dynamically with the text category titles?
$('gon.top_level').each(function(){
var lnk = $('<h5>' + this.main_category + " >" + '</h5>')
.find('a').data({'category':$(this).category_id,'anotherKey':'value'});
$("#top_level").append(lnk);
});
$("#top_level").on('click', 'a', function(){
console.log($(this).data('category'));
console.log($(this).data('anotherKey'));
});
To set data use $(elment).data({key:value});
To get data use $(elment).data(key);

Metro Javascript. Error grouping items. ui.js firstItemIndexHint property

Well, I'm pulling my hair out with an error grouping items to render in a listview.
When I set the items/groups datasources to the list thru WinJS.UI.setOptions I get an error in ui.js at line 16812 saying "Unable to get property 'firstItemIndexHint' of undefined or null reference".
I have other pages in my application where grouping works fine but this one doesn't seems to work. I use the same binding method in all of them and I can't find any difference between them that causing this error.
Can anyone tell me what's making the following code crash?.
Thanks.
javascript page code in ready function:
var arr = new Array();
//fill in an array with sample data.
//name property is the one used for grouping
//nm is rendered in the item template.
for (var i = 0; i < 10; i++) {
arr.push({
name: "group" + (i % 5),
nm: "namer" + i,
});
}
//create a list based on the array.
var items = new WinJS.Binding.List(arr);
//group items by the name property (key selector function) and
//use it for rendering the group template (group data function)
var groupDataSource = items.createGrouped(
function (item) {
return item.name;
},
function (item) {
return {
name: item.name,
click: function () {
nav.navigate("mynavpage.html");
}
};
});
//get a reference to the listview control
var listView = element.querySelector(".itemGroups").winControl;
//set templates and datasources to listview
//here's where calls to base.js/ui.js are made and where app fails.
WinJS.UI.setOptions(listView, {
groupHeaderTemplate: $(".headerTemplate")[0],
itemTemplate: $("#itemTemplate1")[0],
itemDataSource: items.dataSource,
groupDataSource: groupDataSource.groups.dataSource,
});
html page code
<!-- group header template -->
<div class="headerTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
<h2 class="group-title" data-win-bind="textContent: name" role="link">
</h2>
</div>
<!-- item template -->
<div id="itemTemplate1" data-win-control="WinJS.Binding.Template" style="display: none">
<div class="itemTemplate item1x1" id="item1">
<div class="itemText">
<h4 class="itemTitle win-type-ellipsis" data-win-bind="textContent: nm"></h4>
</div>
</div>
</div>
<!-- fragment section -->
<div class="myPage fragment">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back" disabled></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pageTitle">Page Title</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<!-- listview Grid -->
<div class="itemGroups" aria-label="List of groups" data-win-control="WinJS.UI.ListView"
data-win-options="{ tapBehavior: 'toggleSelect' }">
</div>
</section>
</div>
You need to use the groupDataSource for both the items and the groups.
WinJS.UI.setOptions(listView, {
groupHeaderTemplate: $(".headerTemplate")[0],
itemTemplate: $("#itemTemplate1")[0],
itemDataSource: groupDataSource.dataSource,
groupDataSource: groupDataSource.groups.dataSource,
});

Categories

Resources