TIBlob passed through application-level event becomes NULL on the receiving end - javascript

I have a very simple app where the user selects an image from the iOS photo gallery.
The TIBlob passed to Titanium.Media.openPhotoGallery.success event is then passed to an application-level event.
The issue is that the TIBlob is NULL when the application level event is received.
Below is a complete code sample.
Titanium.UI.setBackgroundColor('#000');
var win = Ti.UI.createWindow({title: 'Camera Test', exitOnClose: true, fullscreen: true, backgroundColor: '#ffffff'});
var bt = Ti.UI.createButton({'title': 'Gallery', top: 10, width: 200, height: 50});
bt.addEventListener('click', function(e) {
Titanium.Media.openPhotoGallery({
success:function(event) {
if(event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO) {
alert(event.media);
Ti.App.fireEvent('uploadImage', {image: event.media, source: 'gallery'});
}else {
alert('Image was not uploaded because the type was invalid.');
}
},
cancel:function() {
},
error:function(err) {
alert('Error selecting image from gallery: ' + err);
Ti.API.error(err);
},
allowEditing: false,
autohide: true,
mediaTypes:[Ti.Media.MEDIA_TYPE_PHOTO]
});
});
Ti.App.addEventListener('uploadImage', function(e) {
alert(e.image);
alert(e.source);
});
win.add(bt);
win.open();
Any suggestions?

The Appcelerator Guides say that objects passed through and event must be JSON-serializable https://wiki.appcelerator.org/display/guides/Event+Handling#EventHandling-Firingevents. A TiBlob is not serializable, so I think the blog is not making it through the event.
If this really is a very simple app, I would suggest changing that to a function call instead of firing an event and the blob will be preserved. However, if this absolutely needs to be an event, you could pass event.media.nativePath instead and then read a blob out of that when you actually need to do something with it.

Related

How to disable fullcalendar

I want to set authorities on my calendar. Only certain users can update the data. While all users can only see the event and are not allowed to make any changes. I'm using select function to popup modals. Can fullcalendar be disabled? I want it to be like readonly function. Which means all users can read the data. I try to do like this :
if(#ViewBag.User == "Admin")
{
editable = true,
}
But it doesn't work. The events can still be edited since I also set that attribute inside my JSON codes for events. Is there any way to solve this? Thanks
Try this,
editable = false
and set URL for the event as
url: '/Event/Create/'
if you do not want any redirection to add use below link
url: 'Javascript:'
User this URL in events section. like this
$('#calendar').fullCalendar({
editable = false,
events: [
{
title: 'My Event',
start: '2010-01-01',
url: 'http://google.com/'
},
{
title: 'My Event',
start: '2010-01-01',
url: 'Javascript:'
}
// other events here
],
eventClick: function(event) {
if (event.url) {
window.open(event.url);
return false;
}
}
});

Dynamically changing url in sharrre Jquery

My question is the following:
I have multiple filters on my page, that filter events schedule dynamically, so when I click on any of the filters, my url changes without reloading the page.
For example:
http://.../schedule/#Screening,Free
http://.../schedule/#Talk,Expo
Then, I have share buttons with Sharrre:
.social.social--share-filters
a.icon.icon-twitter.js-twitter-filters(href="#", target="_blank")
a.icon.icon-linkedin2.js-linkedin-filters(href="#", target="_blank")
a.icon.icon-facebook.js-facebook-filters(href="#", target="_blank")
$('.js-facebook-filters').sharrre({
share: {
facebook: true,
},
url: window.location.href,
enableTracking: false,
enableHover: false,
click: function(api, options) {
api.simulateClick();
api.openPopup('facebook');
}
});
Inspite of that fact that inside sharrre I have url variable that equals to current link, it shares only that link which is derived when page is loaded for the first time.
I tried to put it inside click event on the icons - that does not work.
I tried to put sharrre inside a function (eg. initialiseShare) and do window.initialiseShare = initialiseShare; - that also does not work.
And I tried to remove and append the button, changing data-url attribute, and it also does not work.
function initialiseShare(link) {
$('.js-twitter-filters').sharrre({
share: {
twitter: true,
},
enableTracking: false,
enableHover: false,
click: function(api, options) {
api.simulateClick();
api.openPopup('twitter');
} }); }
+
$(document).ready(function() {
initialiseShare();
$('.js-twitter-filters').on('click', function(){
var clone = $('.js-twitter-filters').clone();
$('.js-twitter-filters').remove();
$('.social--share-filters').append(clone);
$('.js-twitter-filters').data('url', window.location.href);
initialiseShare();
return false;
});
});
+
jade for the icon
.social.social--share-filters
a.icon.icon-twitter.js-twitter-filters(href="#", target="_blank" data-url="#")
Please, help!
Thank you in advance!
P.S. I can use any other solution except those which could lead to buttons which cannot be customised in design.
Try this:
$('body').on('DOMNodeInserted', '.js-twitter-filters', function(e) {
$(this).sharrre({
share: {
twitter: true,
},
enableTracking: false,
enableHover: false,
click: function(api, options) {
api.simulateClick();
api.openPopup('twitter');
}
});
});
Explanation:
You're trying to bind to dynamically loaded elements. When your script executes on page load, the elements are not available for jQuery to perform the binding with "sharrre" - so you can use the .on() live binding delegate to bind to elements after insertion.
Reference:
http://api.jquery.com/on/

TinyMCE4 file_picker_callback - return additional params

I am using my own custom file picker with TinyMCE 4's new file_picker_callback function. The documentation on this isn't great, so credit goes to Fred for getting me this far - https://stackoverflow.com/a/24571800/2460995
The custom file picker is working and when you click on an image it fills in the "Source" and also the "Dimensions". I'm just wondering if there is any way to automatically fill in the "Image description" field as well.
The information for the images is generated from a database table, so I already have a description and it would be nice to automatically fill it in for the user. After trying various ways of passing the data back I'm struggling to understand how it can be done.
Code for TinyMCE:
tinymce.init({
...
file_picker_callback: function(callback, value, meta) {
myImagePicker(callback, value, meta);
}
});
function myImagePicker(callback, value, meta) {
tinymce.activeEditor.windowManager.open({
title: 'Image Browser',
url: '/media/browser/1?type=' + meta.filetype,
width: 800,
height: 550,
}, {
oninsert: function (url) {
callback(url);
}
});
};
Code for the Custom File Picker:
$(function(){
$('.img').on('click', function(event){
mySubmit('/upload/' + $(this).data('filename'));
});
});
function mySubmit(url) {
top.tinymce.activeEditor.windowManager.getParams().oninsert(url);
top.tinymce.activeEditor.windowManager.close();
}
My javascript knowledge isn't the greatest yet as I'm quite new to it, so if you could please illustrate any answers with examples and/or clear logic that would be very useful and much appreciated.
I was having the same problem, and came up with the following solution:
Update your myImagePicker function to be (note the new objVals parameter to the oninsert function):
function myImagePicker(callback, value, meta) {
tinymce.activeEditor.windowManager.open({
title: 'Image Browser',
url: '/media/browser/1?type=' + meta.filetype,
width: 800,
height: 550,
}, {
oninsert: function (url, objVals) {
callback(url, objVals);
}
});
};
Update your mySubmit function to be (note the objVals parameter that is passed to oninsert):
function mySubmit (url, objVals) {
top.tinymce.activeEditor.windowManager.getParams().oninsert(url, objVals);
top.tinymce.activeEditor.windowManager.close();
return false;
}
Update the places that you call mySubmit to fill-in the objVals object.
For example:
mySubmit("https://google.com", { text: "Go To Google", target: '_blank' });
The properties to fill-in for objVals change based on the type of calling dialog, and are (partially) documented here.
For the link dialog:
mySubmit("https://google.com", { text: "Go To Google", target: '_blank' });
For the image dialog:
mySubmit("image.jpg", { alt: "My image" });
For the mediadialog:
mySubmit("movie.mp4", {source2: 'movie-alt.ogg', poster: 'movie-image.jpg'});

ExtJS 4 - How to download a file using Ajax?

I have a form with various textfields and two buttons - Export to Excel and Export to CSV.
The user can provide the values to different fields in the form and click one of the buttons.
Expected behaviour is that an Ajax request should be fired carrying the values of fields as parameters and the chosen file (Excel/CSV as per the button click) should get downloaded (I am not submitting the form as there needs to be done some processing at the values before submit).
I have been using the following code in success function of Ajax request for the download:
result = Ext.decode(response.responseText);
try {
Ext.destroy(Ext.get('testIframe'));
}
catch(e) {}
Ext.core.DomHelper.append(document.body, {
tag: 'iframe',
id:'testIframe',
css: 'display:none;visibility:hidden;height:0px;',
src: result.filename,
frameBorder: 0,
width: 0,
height: 0
});
The above code has been working fine in the case when the file is created physically at the server. But in my current project, the file is not created at the server, rather the contents are just streamed to the browser with proper headers.
Thus, is there a way to download a file using Ajax when the file is not present at the server physically? Just to add that I have a long list of parameters which I need to send to the server and hence can not add them all to the src of iframe.
Could anyone guide at this?
Thanks for any help in advance.
You may use component like this:
Ext.define('CMS.view.FileDownload', {
extend: 'Ext.Component',
alias: 'widget.FileDownloader',
autoEl: {
tag: 'iframe',
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
},
stateful: false,
load: function(config){
var e = this.getEl();
e.dom.src = config.url +
(config.params ? '?' + Ext.urlEncode(config.params) : '');
e.dom.onload = function() {
if(e.dom.contentDocument.body.childNodes[0].wholeText == '404') {
Ext.Msg.show({
title: 'Attachment missing',
msg: 'The document you are after can not be found on the server.',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
})
}
}
}
});
Put it somewhere in viewport, for example:
{
region: 'south',
html: 'South',
items: [
{
xtype: 'FileDownloader',
id: 'FileDownloader'
}
]
}
Do not forget to require it in your viewport class:
requires: [
'CMS.view.FileDownload'
]
Action handler may look like this:
var downloader = Ext.getCmp('FileDownloader')
downloader.load({
url: '/attachments/' + record.get('id') + '/' + record.get('file')
});
It's very important to have Content-Disposition header in response, otherwise nothing is downloaded.
Regards go to http://www.quispiam.com/blog/post.php?s=2011-06-09-download-a-file-via-an-event-for-extjs4
This thing works for me.

Extjs: Tree, Selecting node after creating the tree

I have a simple TreePanel. I would like to select a particular node upon loading it. The nodes are from a remote file (json).
The tree is loading as expected. However, the node is not being selected. Firebug shows node as undefined. This perhaps because of the async property. But, I an unable to configure this other wise, or specify the node be selected.
Any suggestions welcomed, and thank you.
LeftMenuTree = new Ext.tree.TreePanel({
renderTo: 'TreeMenu',
collapsible: false,
height: 450,
border: false,
userArrows: true,
animate: true,
autoScroll: true,
id: 'testtest',
dataUrl: fileName,
root: {
nodeType: 'async',
iconCls:'home-icon',
expanded:true,
text: rootText
},
listeners: {
"click": {
fn: onPoseClick,
scope: this
}
},
"afterrender": {
fn: setNode,
scope: this
}
});
function setNode(){
alert (SelectedNode);
if (SelectedNode == "Orders"){
var treepanel = Ext.getCmp('testtest');
var node = treepanel.getNodeById("PendingItems");
node.select();
}
}
I use this code in the TreeGrid to select a node
_I.treeGrid.getSelectionModel().select(_I.treeGrid.getRootNode());
I haven't tried this in a TreePanel but since the TreeGrid is based on it I'll just assume this works. I used the load event of the loader to plugin similar code after the XHR request was done, so try to write your setNode function like this:
var loader = LeftMenuTree.getLoader();
loader.on("load", setNode);
function setNode(){
alert (SelectedNode);
if (SelectedNode == "Orders"){
var treepanel = Ext.getCmp('testtest');
treepanel.getSelectionModel().select(treepanel.getNodeById("PendingItems"));
}
}
this work for me...
var loader = Ext.getCmp('testtest').getLoader();
loader.on("load", function(a,b,c){
b.findChild("id",1, true).select(); // can find by any parameter in the json
});
I have documented a way to accomplish something very similar here:
http://www.sourcepole.ch/2010/9/28/understanding-what-s-going-on-in-extjs
what you'll need to make sure is that the node that you are selecting is visible. You can accomplish that by traversing the tree and node.expand()ing all the nodes parents (from the root down).
This is because the node isn't really selectable until the tree has been rendered. Try adding your node selection to an event listener listening for the render event.
If you're using a recent enough version of ExtJS then I find using ViewModels and the Selection config far easier for this kind of thing.
Something like:
LeftMenuTree = new Ext.tree.TreePanel({
renderTo: 'TreeMenu',
collapsible: false,
height: 450,
border: false,
userArrows: true,
animate: true,
autoScroll: true,
id: 'testtest',
dataUrl: fileName,
bind: {
Selection: '{SelectedNode}'
},
root: {
nodeType: 'async',
iconCls:'home-icon',
expanded:true,
text: rootText
},
listeners: {
"click": {
fn: onPoseClick,
scope: this
}
"afterrender": {
fn: setNode,
scope: this
}
});
(You'll need to either have a ViewModel set up in the TreePanel or the owning view)
Then assuming you're using a ViewController and setNode is a member:
setNode: function(){
var nodeToSelect = // code to find the node object here
this.getViewModel().set('Selection', nodeToSelect);
}
The nice thing about the ViewModel approach is that it seems to just handle all of the rendering / data loading issues automatically.

Categories

Resources