I'm currently developping a WebApp with KendoMobile.
I have use a scrollView to display an informations bar like you can see on the picture below :
The problem comes when I click on a marker.
I wrote a function that change the page of the scrollview to match the marker I clicked.
Here is the code of the method :
google.maps.event.addListener(markerObj, 'click', function() {
var page = fournisseursArrayIndexOf(markerObj.data["ID"]);
console.log("marker title : " + markerObj.title + " / footer page : " + page);
var footer = $("#footer").data("kendoMobileScrollView");
var curpage = footer.page;
markers[curpage].setIcon(normalImg);
markerObj.setIcon(selectedImg);
footer.scrollTo(page);
//map.panTo(markerObj.position);
});
I read here that if I use the scrollTo method with a single parameter (the page index that I want to show), there will be a transition animation by default.
But nothing happens, I mean the page do change, but there no animation.
I searched on Kendo forum but the only topic I found is this one but it's the exact opposite of what I want : He want to delete the animation when I want to have it.
But that helps me kind of because it mean that having an animation is possible.
Does someone know the solution to this problem ?
Problem solved ! Sort of...
I tested many things by modifying the code of the KendoMobileScrollView and I found that the animation that is supposed to be displayed when you call the scrollTo method doesn't work with scrollview filled with a template.
So if someone encounter the same problem : you'll have to write a loop that will create the pages of your scrollview and insert it in the DOM.
Looks like this :
var htmlToAppen = "<div data-role=\"page\>"";
for(var i = 0 ; i < yourObjectsArray.length ; i++) {
var curObj = yourObjectsArray[i];
htmlToAppen += "<div> objName : " + curObj.name + "</div>";
htmlToAppen += "</div>";
}
$("#yourScrollDiv").append(htmlToAppend);
$("#yourScrollDiv").kendoMobileScrollView({
enablePager : false
});
Related
as the Toolbar or Titlearea on scroll animation feature is referenced in the last section of the Toolbar API, and also in this great video tutorial (starting at about min 45), the animation works well under given circumstances.
I was not able to find any documentation about what these have to be, however I found one circumstance, in which it does not work. Here is a working example to demonstrate the problem:
Form hi = new Form("Title", new BoxLayout(BoxLayout.Y_AXIS));
EncodedImage placeholder = EncodedImage
.createFromImage(Image.createImage(hi.getWidth(), hi.getWidth() / 5, 0xffff0000), true);
URLImage background = URLImage.createToStorage(placeholder, "400px-AGameOfThrones.jpg",
"http://awoiaf.westeros.org/images/thumb/9/93/AGameOfThrones.jpg/400px-AGameOfThrones.jpg");
background.fetch();
Style stitle = hi.getToolbar().getTitleComponent().getUnselectedStyle();
stitle.setBgImage(background);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(15);
// hi.setLayout(new BorderLayout()); // uncomment this for the animation to break
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(contentContainer);
// hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(anim);
hi.show();
With my current app and the codesample from the Toolbar API (which is roughly adapted here), I found out that the onScrollAnimation event is not being called, when a scroll occurs inside a BorderLayout. Even when I have a separate container, which is not the contentpane itself, and I set setScrollableY(true); to true, the animation works properly. The animation stops working, when this very container is put into Center of the Form, via Borderlayout. in the example above, the layout is exactly the same, as there are no other components in other areas of course, but it breaks the animation.
How to solve this? In my app, I have the need for a BorderLayout but still want to use this cool feature. Also, this is a very un-intuitive feature, if it works for some, but not all layouts. It should be completely layout-agnostic and work in every case.
Thank you.
The adapter is bound to the forms content pane scrolling so it won't work if you have a border layout in here. In that case scrolling isn't detected because the code just isn't aware of the scrolling. It would need to track the scrolling of any component in the UI to detect that scrolling.
as hinted by Shai, the solution is the following:
hi.setLayout(new BorderLayout());
Container contentContainer = new Container(BoxLayout.y());
contentContainer.setScrollableY(true);
// add some elements so we have something to scroll
for (int i = 0; i < 50; i++)
contentContainer.add(new Label("Entry " + i));
hi.add(BorderLayout.CENTER, contentContainer); // use this line instead of the above for the animation to break
ComponentAnimation anim = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(contentContainer, anim);
instead of using the onTitleScollAnimation to just add the animation, provide your own scrollable "body" or content container as the first argument, appended by the animation(s).
I'm using CKEditor and I want to indent just the first line of the paragraph. What I've done before is click "Source" and edit the <p> style to include text-indent:12.7mm;, but when I click "Source" again to go back to the normal editor, my changes are gone and I have no idea why.
My preference would be to create a custom toolbar button, but I'm not sure how to do so or where to edit so that clicking a custom button would edit the <p> with the style attribute I want it to have.
Depending on which version of CKE you use, your changes most likely disappear because ether the style attribute or the text-indent style is not allowed in the content. This is due to the Allowed Content Filter feature of CKEditor, read more here: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
Like Ervald said in the comments, you can also use CSS to do this without adding the code manually - however, your targeting options are limited. Either you have to target all paragraphs or add an id or class property to your paragraph(s) and target that. Or if you use a selector like :first-child you are restricted to always having the first element indented only (which might be what you want, I don't know :D).
To use CSS like that, you have to add the relevant code to contents.css, which is the CSS file used in the Editor contents and also you have to include it wherever you output the Editor contents.
In my opinion the best solution would indeed be making a plugin that places an icon on the toolbar and that button, when clicked, would add or remove a class like "indentMePlease" to the currently active paragraph. Developing said plugin is quite simple and well documented, see the excellent example at http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1 - if you need more info or have questions about that, ask in the comments :)
If you do do that, you again need to add the "indentMePlease" style implementation in contents.css and the output page.
I've got a way to indent the first line without using style, because I'm using iReport to generate automatic reports. Jasper does not understand styles. So I assign by jQuery an onkeydown method to the main iframe of CKEditor 4.6 and I check the TAB and Shift key to do and undo the first line indentation.
// TAB
$(document).ready(function(){
startTab();
});
function startTab() {
setTimeout(function(){
var $iframe_document;
var $iframe;
$iframe_document = $('.cke_wysiwyg_frame').contents();
$iframe = $iframe_document.find('body');
$iframe.keydown(function(e){
event_onkeydown(e);
});
},300);
}
function event_onkeydown(event){
if(event.keyCode===9) { // key tab
event.preventDefault();
setTimeout(function(){
var editor = CKEDITOR.instances['editor1'], //get your CKEDITOR instance here
range = editor.getSelection().getRanges()[0],
startNode = range.startContainer,
element = startNode.$,
parent;
if(element.parentNode.tagName != 'BODY') // If you take an inner element of the paragraph, get the parentNode (P)
parent = element.parentNode;
else // If it takes BODY as parentNode, it updates the inner element
parent = element;
if(event.shiftKey) { // reverse tab
var res = parent.innerHTML.toString().split(' ');
var aux = [];
var count_space = 0;
for(var i=0;i<res.length;i++) {
// console.log(res[i]);
if(res[i] == "")
count_space++;
if(count_space > 8 || res[i] != "") {
if(!count_space > 8)
count_space = 9;
aux.push(res[i]);
}
}
parent.innerHTML = aux.join(' ');
}
else { // tab
var spaces = " ";
parent.innerHTML = spaces + parent.innerHTML;
}
},200);
}
}
Is there a way to access the jqGrid's columnChooser's multiselect API objects? I need to call those objects to update the data on ColumnChooser pop-up dialog.
In the snapshot below, is the customized ColumnChooser pop-up dialog. The HTML combo when selected/changes would then change the $ui.multiselect sections (avaiable & unavailable columns).
In the 2nd snapshot below is the view souce using Firefox's firebug and it doesn't have me the option to toggle the 2 columns.
Is there a way to access ColumnChooser's API instead, to manually toggle the columns on the ColumnChooser but not touch the jqGrid's columns? How can I accomplish this?
Thanks...
[Snapshot #1]...
[Snapshot #2]...
After a few days of Google surfing, piecing together sample script from lots of example api and coming up with JQuery to find the html path to a clickable anchor link.
Updated Solution
The "parmSavedBuildDataFormValueColumnModelSetting" value is the colModel's name you passed on to it, whether it be the values you saved from the database or cookie, or anything for populating the MultiSelect "selected" box-windows.
function JqgridColumnChooserSavedBuildsRecordsMultiselectDialogToggler(parmSavedBuildDataFormValueColumnModelSetting) {
//Re-order the $.ui.multiselect's columns in 2 boxed-windows (available & unavailable)...
//http://stackoverflow.com/questions/10439072/add-remove-column-handler-on-jqgrid-columnchooser
//http://stackoverflow.com/questions/11526893/jqgrid-columnchooser-unselected-columns-on-the-right-in-alphabetical-order
var $jqgridColumModelSetting = $('#' + jqgridSpreadsheetId).jqGrid('getGridParam', 'colModel');
var $jqgridColumNameSetting = $('#' + jqgridSpreadsheetId).jqGrid('getGridParam', 'colNames');
//Remove all of the "selected" columns having "-" icon...
//09/11/2013 - This "selected" columns with hyperlink click event does not work too well as it cause 1/3 of all columns not to be visible, so let' use the "Remove All" hyperlink instead...
//#$('#colchooser_' + jqgridSpreadsheetId + ' ul.selected a.action').click();
$('#colchooser_' + jqgridSpreadsheetId + ' div.ui-multiselect div.selected a.remove-all').click();
//Add back the "available" columns having "+" icon, only the one that match the SavedBuilds data...
$.each(parmSavedBuildDataFormValueColumnModelSetting.split('|'), function (i1, o1) { //##parmSavedBuildDataFormValueColumnModelSetting.forEach(function (i, o) {
$.each($jqgridColumModelSetting, function (i2, o2) {
if (o2.name == o1) {
$('#colchooser_' + jqgridSpreadsheetId + ' ul.available li[title="' + $jqgridColumNameSetting[i2] + '"] a.action').click();
return false; //This only break the foreach loop [while "return true" resume the loop] (This have nothing to do with function's returned value)...
}
});
});
}
I have a problem with my product view. I want to display product data. each product is a "box" with an image and text. I want to display six products on a panel. As of the fact that i have many products i want to have a "carousel like view". My idea was the following: Place 6 products on a panel. Load 3 panels and place each panel as a carousel item so that i can swipe to get to another "page".
To save performance I tried to always have only 3 items in the carousel. The active "page" and the page before, and the page after, so that I can swipe to left/right and the next page can be loaded.
I tried to put my logic in the "onActiveItemChange"-Listener of the carousel, but I had massive problems with adding/removing carousel items. So my Question is is it possible to do what i want to accomplish?
Is there a better alternative? Of course my data is in a store, but I don't want that standard list view.
Another Question: Because my first attempt with the carousel failed i tried to build a Ext.Container (card layout) with the panels on it. But how can I listen to a swipe event on a Panel???
thanks for help ;-)
Even I am doing the same, using carousel & a store. Every page of carousel is a view(panel) which would have 4/6 child views(panels). On store load I am creating those children and then divide them into pages and add those pages to carousel.
This is working fine for me and on activeItemChange I am loading more pages:
activeitemchange: function(container, value, oldValue, eOpts) {
var activeItemIndex = container.getActiveIndex();
var galleryTotal = container.getInnerItems() ? container.getInnerItems().length : 0;
if ((activeItemIndex + 1 == galleryTotal)) {
console.log("At last page, time to load");
var store = this.config.store;
store.nextPage({ addRecords: true });
}
}
I think I understand your issue. Assuming you've got 3 items and you're always viewing the middle one (as you move forward, item 0 gets destroyed and one item gets created). And assuming that each item has an id associated with its location in the list.
var current_item = Ext.getCmp('carousel_name').getActiveItem().getId();
current_item = Number(current_item.replace('item', ''));
//Objects to create
var next_item = current_item + 1;
var previous_item = current_item - 1;
//Objects to destroy
var next2_item = current_item + 2;
var previous2_item = current_item - 2;
//Create items
var createItem = function(item_location, type){
var carousel_item = create_content(item_location);
if(type == 'next'){
Ext.getCmp('carousel_name').add(carousel_item);
}else if(type == 'previous'){
Ext.getCmp('carousel_name').insert(0, carousel_item);
Ext.getCmp('carousel_name').setActiveItem(1);
}
}
createItem(next_item,'next');
createItem(previous_item,'previous');
//Destroy items
if(Ext.getCmp('item'+previous2_item)){
Ext.getCmp('carousel_name').getItems().items[0].destroy();//This is a hack, for some reason with the above commented out line, the item was getting destroyed but wasn't being removed from carousel_name
}
if(Ext.getCmp('item'+next2_item)){
Ext.getCmp('carousel_name').getItems().items[Ext.getCmp('carousel_name').getMaxItemIndex()].destroy();//This is a hack, consistency with previous destroy (above)
}
I'm using SlickGrid with the pager plugin. My intent is to display line items in SlickGrid and allow the user to double click on a row to get more detail. I have code that seems to work fine but it feels as though I'm doing this the hard way:
grid.onDblClick.subscribe(function(e, args) {
var selectedIndex = parseInt(grid.getSelectedRows());
var pageInfo = dataView.getPagingInfo();
var pageSize = pageInfo.pageSize;
var pageNum = pageInfo.pageNum;
var idx = pageSize*pageNum + selectedIndex;
var asset = rows[idx].assetName;
alert("Selected Asset is " + asset);
});
I've seen other questions posted where people did a grid.getData()[selectedIndex] or a dataView.getItemById(selectedIndex), but since selectedIndex is always a 0 to something number, I always got data from the first page in my list regardless of which page I was on. Is there a direct way to map a selected index on a page to the actual row in the data array? Again, the code above seems to work fine - just feels like I'm missing an obvious method somewhere.
grid.onDblClick.subscribe(function(e, args) {
alert("Selected asset is " + args.item);
alert("Or " + grid.getData().getItem(args.row));
alert("Or " + grid.getDataItem(args.row));
});