I've been trying to utilize the Trello API via JSFiddle and haven't been able to get it to work (I have very limited JS/JSON knowledge). I need to create a card under a specific list, using the API.
function PostStuff()
{
$(document).ready(function(){
Trello.authorize({
interactive: true,
type: "popup",
expiration: "never",
name: "surveyrequest",
persist: "true",
success: function() { onAuthorizeSuccessful(); },
error: function() { onFailedAuthorization(); },
scope: { read: true, write: true}
});
function onAuthorizeSuccessful() {
Trello.post("cards", { name: "Card created for test", desc: "this is a test", idList: "........", due: null, urlSource: null});
}
});
}
I have JQuery and the Trello API included. I blanked out the idList in the code for security purposes. I confirmed that the code does execute the onAuthorizeSuccessful() function.
How can I modify this to create a Trello card?
function Auth() {
Trello.authorize({
type: 'popup',
name: 'your app name',
scope: {
read: true,
write: true },
expiration: '30days',
success: authenticationSuccess,
error: authenticationFailure
});
var authenticationSuccess = function(data){ /*your function stuff*/};
var authenticationFailure = function(data){ /*your function stuff*/};
}
this code works for me. i get function Auth() triggered on button click.
Also, you might have some issues with tokens which are expired, so Trello.deauthorize(); could be used on create new card failure function (it all depends on create new card error message).
regarding the create a new card...
var newCard =
{name: jQuery('input#tc_title').val(),
desc: jQuery('textarea#tc_desc').val(),
pos: "top",
idList: trello_list_id_var
};
Trello.post('/cards/', newCard, success, error);
var success = function(data){ /*..............*/}
var error= function(data){ /*..............*/}
in success/error functions you are able to check the error data
EDIT:
also i think that Trello.post("cards" ... should be replaced with Trello.post("/cards/" ... that might be the problem...
Related
I'll explain the scenario with an example.
Suppose I have following JS code:
$.ajax({
url: '/Department/GetAllUsers',
type: "POST",
data: data,
success: function (result) {
//Some Code
},
error: function () {
//Some Code
}
});
And I want to restrict call to that action of the controller. So I have written following Custom ES Lint rule for this:
module.exports = {
meta: {
type: "problem",
docs: {
description: "Prohibited Method",
category: "Method",
recommended: true,
url: ""
},
messages: {
messageDefault: "This method is Prohibited to use"
},
fixable: "code",
schema: [] // no options
},
create: function (context) {
return {
Literal(node) {
var literalValue = node.value.toString();
var cont = literalValue.split("/").filter(x => x.length > 1);
{
if (cont[0] === 'Department' && cont[1] === 'GetAllUsers') {
context.report({
node: node,
messageId: "messageDefault",
});
}
}
}
};
}
};
So here I am restricting use of 'Department/GetAllUsers' which is working great. The problem arises when I split the string or assign the string to a variable. For example
var controller = "Department";
var action = "GetAllUsers";
$.ajax({
url: "/" + controller + "/" + action,
//or '/Department/' + 'GetAllUsers'
type: "POST",
data: data,
success: function (result) {
//Some Code
},
error: function () {
//Some Code
}
});
Here the restriction does not work, is there a way in which I can resolve the variable values at the url? Is this even possible using ESLint?
In short I want something like the context.SemanticModel.GetSymbolInfo(node) which is used in Roslyn for C# code analysis.
Thanks
You can use ESLint's scope manager
https://eslint.org/docs/developer-guide/scope-manager-interface
There are many examples of using the scope manager in ESLint's own codebase:
https://github.com/eslint/eslint/search?q=getScope
Using this API you can follow the variable reference and inspect its assignments.
Note that this has some limitations. For example you won't be able to track values across module boundaries or function boundaries.
I am using 5.3.2 in basic mode as I need control over the UI.
I have added code to allow the uploads and then created little UI elements that can then trigger a deletion. I need to know the filename when I am deleting. So I used setDeleteFileParams but nothing is attached to the request.
var uploader = new qq.FineUploaderBasic({
button: document.getElementById('btnUploadFiles'),
debug: true,
autoUpload: true,
request: {
paramsInBody: true,
endpoint: '../myendpoint.htm',
params: {
tempID: 'myidwhatever'
}
},
deleteFile: {
enabled: true,
forceConfirm: false,
method: 'POST',
endpoint: '../myendpoint.htm'
},
callbacks: {
onSubmitted: function(id, name){
//do work
},
onDelete: function(id) {
this.setDeleteFileParams({filename: this.getName(id)}, id);
},
onDeleteComplete: function(UID, xhr, isError){
//remove my UI element
},
onComplete: function(UID, name, responseJSON, xhr) {
//create an element and stick it in
}
}
})
//ADD THE DELETE BUTTON ACTIONS
$('uploadedFiles').addEvent("click:relay(.deleteMyFile)", function(event, element) {
event.preventDefault();
arr = element.id.split('_')
uploader.deleteFile(arr[1]);
});
Im using Mootools as my JS framework. Everything triggers ok and the console logs out the filename correctly when I delete a file but when I look at the request there is no 'filename' parameter.
Thanks for any help.
By the time your onDeleteFile callback has been called, the file is already setup to be deleted. If you'd like to influence (or prevent) the underlying request, you'll need to put your logic inside of a onSubmitDelete callback handler instead.
For example:
callbacks: {
onSubmitDelete: function(id) {
console.log(this.getName(id));
this.setDeleteFileParams({filename: this.getName(id)}, id);
}
}
Parse.com with JavaScript SDK - unnecessary duplictions
Every time I create a Parse object of "message", it duplicates that object in my Parse Core. It is so bizarre. The first time I run the code, everything is fine and Parse will create only one object. But when I run the code again, it will duplicate the most recent object twice. If I run it a third time, it will duplicate the most recent object five times. The number of duplications increases based upon how many objects have already been created. Does anyone have any idea how to make sure that it create one object in my Parse Core backend? Thank you so much!!! I wish I could post a picture, but I am a newbie and stackoverflow wont let me
This is where I create the Parse object:
App.Models.Message = Parse.Object.extend({
className: 'Message',
idAttribute: 'objectId',
defaults: {
name : '',
email : '',
subject : '',
message : ''
}
});
This is where I create an instance of the Parse object, and where I save it to Parse:
App.Views.Contact = Parse.View.extend({
el : '#middle',
template : _.template($('#contactTemp').html()),
events: {
'click .submit' : 'submit',
},
initialize : function () {
this.render();
},
render : function () {
this.$el.html(this.template);
},
submit : function (e) {
e.preventDefault();
var message = new App.Models.Message({
name: $('.nameVal').val(),
email: $('.emailVal').val(),
subject: $('.subVal').val(),
message:$('.messVal').val(),
});
message.save(null, {
success:function() {
console.log("Success");
},
error:function(e) {
alert('There was an error in sending the message');
}
});
}
});
Yes! So I figured out the problem with the help of Hector Ramos from the Parse Developers Google group.
https://groups.google.com/forum/#!topic/parse-developers/2y-mI4TgpLc
It was my client-side code. Instead of creating an event attached to my App.Views.Contact(); a.k.a. - an instance of Parse.View.extend({}), I went ahead and created a 'click' event using jquery within the sendMessage function that I recently defined. If you declare an event in the events object within the Parse view, it will recur over itself if the view wasn't re-initialized or destroyed and recreated properly.
So what happened with me was the submit function that I declared in the events object kept recuring over itself and making duplicate calls to Parse.com. My view was static, it wasn't destroyed properly, re-initialized, or reloaded. You will see what I did below:
Originally I had this:
events: {
'click .submit' : 'submit',
},
& this
submit : function (e) {
e.preventDefault();
var message = new App.Models.Message({
name: $('.nameVal').val(),
email: $('.emailVal').val(),
subject: $('.subVal').val(),
message:$('.messVal').val(),
});
message.save(null, {
success:function() {
console.log("Success");
},
error:function(e) {
alert('There was an error in sending the message');
}
});
} /*end of submit*/
Now I have I completely removed the events object that I had and declared a sendMessage function:
initialize : function () {
this.render();
},
render : function () {
this.$el.html(this.template);
this.sendMessage();
},
sendMessage : function () {
$('.submit').on('click', function(){
var message = new App.Models.Message({
name: $('.nameVal').val(),
email: $('.emailVal').val(),
subject: $('.subVal').val(),
message:$('.messVal').val(),
});
message.save(null, {
success:function() {
console.log("Success");
},
error:function() {
alert('There was an error in sending the message');
}
});
}); /*end of jquery submit*/
}/*end of send message function*/,
And now it works perfectly fine. Credit is due Hector Ramos who is a Parse.com Developer and who helped me realize that the problem was the actual event. If you guys have any easy way of stoping an event from making several duplicate calls to the back or from reoccurring several times, then please let me know.
I am new to extjs, and I try to integrate extjs 5 with django 1.7 on my localhost. I have set the backend and got the rest api work (at /api/), as at https://github.com/MaZderMind/django-vs-extjs , but when the index.html runs app.js, which displays the login page, it seems that:
The controller file (Login.js) isn't loaded,
the launch function is not executed.
In firebug I can see that it reads the function definition and then returns without executing it automatically (also, when defining controller it steps over like it is simple command, but on the require statement steps into the function that fetches them), hence the login page is not displayed. But the other js files (for authentication) are loaded, as I see in console. Do you have any ideas what is happening? The codes are:
app.js
Ext.Loader.setConfig({enabled:true});
Ext.application({
// base-package of all classes
name: 'MyApp',
// url to load js-files from - adapted to django project
appFolder : 'static/static',
// required controllers
controllers: ['Login'],
// other required components
requires: [
'MyApp.helper.CrsfTokenHelper',
'MyApp.helper.PhantomStoreInserter'
],
// application launch method
launch: function () {
// save the scope
var app = this;
console.log('launched');
// ensure the user is logged in before showing her the main navigation with all our application goodies
app.getController('Login').ensureLoggedIn(function(userinfo) {
console.log('Login-Controller ensured that user', userinfo.username, 'is is currently loggeg in. Proceeding to navigation.')
// upate display of the navigation conteoller and show it
//app.getController('Navigation')
//.updateUserinfo(userinfo)
//.view.show();
console.log('Here should be loaded the view after the login page');
});
}
});
Login.js (controller)
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
mixins: ['Ext.mixin.Observable'],
views: ['Login'],
// pointers into the view
refs: [
{ 'ref': 'userField', selector: '#user' },
{ 'ref': 'passField', selector: '#pass' },
{ 'ref': 'submitButton', selector: '#submit' }
],
// stored user information as received from the server
userinfo: null,
// controller initialisation
init: function() {
// save the scope
var loginController = this;
// create an instance of the view
var win = loginController.loginWindow = loginController.getView('Login').create();
this.control({
// register for the login-click
'#submit': {
click: function() {
// retrieve username & password from view
var username = this.getUserField().getValue(), password = this.getPassField().getValue();
// mask the form out
win.mask('Verifying…');
// process the login with the backend
loginController.performLogin(username, password, function(success) {
// the user was successfully authorized
if(success) {
// now request additional information on the user (name and such)
loginController.fetchLoginStatus(function(userinfo) {
// test if the server responded with data as expected
if(userinfo) {
// hide the login-window
win.hide();
// store received information locally
loginController.userinfo = userinfo;
// raise a event on the controller when finished
loginController.fireEvent('login', userinfo);
loginController.fireEvent('ready', userinfo);
}
// we did not receive valid data from the server
// this sould not fail, but if it does, just handle it like a failed login
else {
// disable the login on the form
win.unmask();
// set error-message on password-field
loginController.clearPasswordAndFocus().setPasswordError('Invalid Username or Password!');
}
})
}
// authorization was not successful
// unmask the form, show an error message and restart login process
else {
win.unmask();
loginController.clearPasswordAndFocus().showError('Invalid Username or Password!');
}
})
}
}
});
// register keyboard handler
this.nav = new Ext.KeyNav(win.getEl(), {
// enter key -> login-button click
enter: function() {
loginController.getSubmitButton().fireEvent('click')
}
});
},
// test if the user is logged in.
// if she is, call back immediatly. if she is not, show a login form
// delay the callback until she logged in successfully
ensureLoggedIn: function(callback) {
// save the scope
var loginController = this;
// test if the backend knows us
loginController.fetchLoginStatus(function(userinfo) {
// analyze if a user is logged in
if(userinfo) {
// callback, if she is
loginController.userinfo = userinfo;
loginController.fireEvent('ready', userinfo);
return callback(userinfo);
}
// no, we're not. show the login-window
console.log('no user logged in, showing login-window');
// login-testing and re-trying is handled by the handler set in the init-method
// it raises an event on the controller once it is finished
// we listen on this event and relay it to our callback - but only once
// -> the callback shouldn't be called multiple times
loginController.on('login', callback, {single: true});
// initiate login procedure by showing the login window
loginController.loginWindow.show();
loginController.clearForm();
});
},
// ask the backend if and which user is currently logged in
fetchLoginStatus: function(callback) {
console.info('requesting current userinfo from backend');
Ext.Ajax.request({
url: '/api/auth/user/',
success: function(response) {
// decode json-response
var userinfo = Ext.util.JSON.decode(response.responseText);
// request user permission list
Ext.Ajax.request({
url: '/api/auth/permissions/',
success: function(response) {
// decode json-response
userinfo.permissions = Ext.util.JSON.decode(response.responseText);
// callback with the decoded response
console.log('received userinfo:', userinfo);
callback(userinfo);
},
failure: function(response) {
// callback without info
console.log('received no permission list - nobody logged in');
callback();
}
});
},
failure: function(response) {
// callback without info
console.log('received no userinfo - nobody logged in');
callback();
}
});
},
// submit username & password to the backend
performLogin: function(username, password, callback) {
console.info('trying to log into backend with username=', username, 'password=', password.length, 'Chars');
// send login data via ajax to the server and callback with result
Ext.Ajax.request({
url: '/api/auth/login/',
method: 'POST',
params: {
'username': username,
'password': password
},
success: function(){
callback(true);
},
failure: function() {
callback(false);
}
});
},
// ask the backend to throw away our session which makes us logged out
performLogout: function(callback) {
console.info('trying to log out from backend');
// ensure userinfo is unset
this.userinfo = null;
Ext.Ajax.request({
url: '/api/auth/logout/',
method: 'GET',
success: function(){
callback(true);
},
failure: function() {
callback(false);
}
});
},
// shorthand to test iff userinfo is available
isLoggedIn: function() {
// null -> false, string -> true
return !!this.userinfo;
},
// shorthand to get the current username
getUserinfo: function() {
return this.userinfo;
},
// shorthand to get the current username
getUsername: function() {
return this.isLoggedIn() ? this.getUserinfo().username : null;
},
// shorthand to get the current username
getPermissions: function() {
return this.isLoggedIn() ? this.userinfo.permissions.user_permissions : [];
},
// shorthand to get the current username
isSuperuser: function() {
return this.isLoggedIn() ? this.userinfo.permissions.is_superuser : [];
},
hasPermission: function(permission) {
return this.isLoggedIn() && (this.isSuperuser() || this.getPermissions().indexOf(permission) !== -1)
},
// clears all form elements in the view
clearForm: function() {
this.loginWindow.unmask();
this.getPassField().setValue('').unsetActiveError();
this.getUserField().setValue('').unsetActiveError();
this.getUserField().focus();
return this;
},
// clears the password-field in the view and sets the typing-focus to it
clearPasswordAndFocus: function() {
this.getPassField().setValue('').focus();
return this;
},
// set an error-message on the password-fieldy
setPasswordError: function(msg) {
this.getPassField().setActiveErrors([msg]);
return this;
}
});
Login.js (view)
Ext.define('MyApp.view.Login', {
extend: 'Ext.window.Window',
renderTo: Ext.getBody(),
id: "loginBox",
title: 'Login',
width: 400,
layout: 'form',
bodyPadding: 5,
closable: false,
resizable: false,
draggable: false,
defaultFocus: 'user',
defaultType: 'textfield',
items: [{
itemId: 'user',
fieldLabel: 'Username',
allowBlank: false
},{
inputType: 'password',
fieldLabel: 'Password',
itemId: 'pass',
allowBlank: false
}],
buttons: [{
text: 'Login',
itemId: 'submit'
}]
});
console output:
GET localhost /static/static/helper/CrsfTokenHelper.js?_dc=1414444486439 200 OK 3ms ext-all-debug.js (line 1010)
GET localhost /static/static/helper/PhantomStoreInserter.js?_dc=1414444486439 200 OK 2ms ext-all-debug.js (line 1010)
Thanks anyway!
Well, apparently you are getting errors with your required files. If you comment the requires line inside your Ext.application:
Ext.application({
// base-package of all classes
name: 'MyApp',
// url to load js-files from - adapted to django project
appFolder : 'static/static',
// required controllers
controllers: ['Login'],
// other required components
//requires: [
// 'MyApp.helper.CrsfTokenHelper',
// 'MyApp.helper.PhantomStoreInserter'
//],
...
});
You will see that your Login window will show up. Assuming of course that you have your folder structure setup correctly
index.html
app.js
static/
static/static/
static/static/controller/Login.js
static/static/view/Login.js
I have some global parameters that I want to be sent in every time I call a fetch on a collection... my issue is I don't want to declare the data: { ... } every time I fetch.
Is there a way I can provide default parameters inside the Collection itself with the possibility to add more or override some?
For example:
Instead of doing this every time:
this.articlesCollection.fetch({
dataType: 'jsonp',
data: {
deviceType: GlobalVars.deviceType,
memberId: GlobalVars.memberId,
authToken: GlobalVars.authToken,
targetObjectId: userId,
limit: 50,
excludeArticleBodies: true,
excludeViewedItems: false
},
success: function() {
_this.render();
}
});
I'd like to just provide a one or two parameters and a success function, like this:
this.articlesCollection.fetch({
data: {
targetObjectId: userId
},
success: function() {
_this.render();
}
});
... and have the Collection look something like:
define([
'underscore',
'backbone',
'global',
'utilities',
'models/article/ArticleModel'
], function(_, Backbone, GlobalVars, Utils, ArticleModel){
var ArticlesCollection = Backbone.Collection.extend({
model: ArticleModel,
initialize : function(view) {
this.view = view;
},
dataType: 'jsonp',
data: {
deviceType: GlobalVars.deviceType,
memberId: GlobalVars.memberId,
authToken: GlobalVars.authToken,
limit: 50,
excludeArticleBodies: true,
excludeViewedItems: false
},
url : function() {
return GlobalVars.baseAPIUrl + '/API/GetArticles';
},
parse : function(data) {
return data.Articles;
}
});
return ArticlesCollection;
});
Here's a working jsFiddle with one approach: http://jsfiddle.net/LEuGq/1/
Basically, you configure both an object of defaultParams and params as properties of your collection, which are used to dynamically compute the correct URL when fetch() is called. This way is probably more in alignment with backbone than changing the API of fetch() to accept parameters, which it is not designed to do.
var ParamCollection = Backbone.Collection.extend({
defaultParams: {deviceType: 'raceCar', limit: 42},
params: {},
url: function() {
return "/paramcollection?" + $.param(_.defaults(this.params, this.defaultParams));
}
});
var paramCollection = new ParamCollection();
paramCollection.params.excludeArticleBodies = true;
paramCollection.params.limit = 52;
$("#debug").append(paramCollection.url());
Backbone uses jQuery's ajax call by default, so you can set up anything you need as a default using various methods. See this question for some examples: jQuery's ajaxSetup - I would like to add default data for GET requests only