JavaScript not equals event from jstree - javascript

I have created a tree in Javascript (using jstree) and I am listening to an for events when someone selects a node. I take the type of node from the data that is passed in and want to execute some code if the type is not default.
When I step through this in the debugger, type is "default", yet it steps into the if statement. What am I missing?
$('#mainTree')
.on('select_node.jstree', function (e, data) {
var type = data.node.type;
if (type != "default") {
(I have tried !== as well)

Here is a demo: http://jsfiddle.net/DGAF4/514/
Change the if to make the alert appear. Are you sure you have the types plugin added, as in the demo above (the core.plugins config option)?

Related

JointJs - Discarding the command in CommandManager.cmdBeforeAdd

In my JointJs application, I want to discard particular commands so that they are not added in the Undo/Redo stack.
I followed the exact same code snippet from the JointJs documentation like below:
var commandManager = new joint.dia.CommandManager({
graph: graph,
cmdBeforeAdd: function(cmdName, cell, graph, options) {
options = options || {};
return !options.ignoreCommandManager;
}
});
// ...
// Note that the last argument to set() is an options object that gets passed to the cmdBeforeAdd() function.
element.set({ 'z': 1 }, { ignoreCommandManager: true });
But when I look into the options object in the debug mode, it doesn't contain any property with the name ignoreCommandManager.
I have also tried the below call to set the z value but it didn't work either.
element.set('z', 1 , { ignoreCommandManager: true });
Any idea why the options object is missing this property to ignore the command, please?
Initially, It was failing in Firefox when I posted the question here. The cache was also disabled.
I tried in another browser (Chrome) today without introducing any new changes and it was working without any issues.

e.source.getActiveSheet(); triggers error [duplicate]

Google Apps Script supports Triggers, that pass Events to trigger functions. Unfortunately, the development environment will let you test functions with no parameter passing, so you cannot simulate an event that way. If you try, you get an error like:
ReferenceError: 'e' is not defined.
Or
TypeError: Cannot read property *...* from undefined
(where e is undefined)
One could treat the event like an optional parameter, and insert a default value into the trigger function using any of the techniques from Is there a better way to do optional function parameters in JavaScript?. But that introduces a risk that a lazy programmer (hands up if that's you!) will leave that code behind, with unintended side effects.
Surely there are better ways?
You can write a test function that passes a simulated event to your trigger function. Here's an example that tests an onEdit() trigger function. It passes an event object with all the information described for "Spreadsheet Edit Events" in Understanding Events.
To use it, set your breakpoint in your target onEdit function, select function test_onEdit and hit Debug.
/**
* Test function for onEdit. Passes an event object to simulate an edit to
* a cell in a spreadsheet.
*
* Check for updates: https://stackoverflow.com/a/16089067/1677912
*
* See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
*/
function test_onEdit() {
onEdit({
user : Session.getActiveUser().getEmail(),
source : SpreadsheetApp.getActiveSpreadsheet(),
range : SpreadsheetApp.getActiveSpreadsheet().getActiveCell(),
value : SpreadsheetApp.getActiveSpreadsheet().getActiveCell().getValue(),
authMode : "LIMITED"
});
}
If you're curious, this was written to test the onEdit function for Google Spreadsheet conditional on three cells.
Here's a test function for Spreadsheet Form Submission events. It builds its simulated event by reading form submission data. This was originally written for Getting TypeError in onFormSubmit trigger?.
/**
* Test function for Spreadsheet Form Submit trigger functions.
* Loops through content of sheet, creating simulated Form Submit Events.
*
* Check for updates: https://stackoverflow.com/a/16089067/1677912
*
* See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
*/
function test_onFormSubmit() {
var dataRange = SpreadsheetApp.getActiveSheet().getDataRange();
var data = dataRange.getValues();
var headers = data[0];
// Start at row 1, skipping headers in row 0
for (var row=1; row < data.length; row++) {
var e = {};
e.values = data[row].filter(Boolean); // filter: https://stackoverflow.com/a/19888749
e.range = dataRange.offset(row,0,1,data[0].length);
e.namedValues = {};
// Loop through headers to create namedValues object
// NOTE: all namedValues are arrays.
for (var col=0; col<headers.length; col++) {
e.namedValues[headers[col]] = [data[row][col]];
}
// Pass the simulated event to onFormSubmit
onFormSubmit(e);
}
}
Tips
When simulating events, take care to match the documented event objects as close as possible.
If you wish to validate the documentation, you can log the received event from your trigger function.
Logger.log( JSON.stringify( e , null, 2 ) );
In Spreadsheet form submission events:
all namedValues values are arrays.
Timestamps are Strings, and their format will be localized to the Form's locale. If read from a spreadsheet with default formatting*, they are Date objects. If your trigger function relies on the string format of the timestamp (which is a Bad Idea), take care to ensure you simulate the value appropriately.
If you've got columns in your spreadsheet that are not in your form, the technique in this script will simulate an "event" with those additional values included, which is not what you'll receive from a form submission.
As reported in Issue 4335, the values array skips over blank answers (in "new Forms" + "new Sheets"). The filter(Boolean) method is used to simulate this behavior.
*A cell formatted "plain text" will preserve the date as a string, and is not a Good Idea.
Update 2020-2021:
You don't need to use any kind of mocks events as suggested in the previous answers.
As said in the question, If you directly "run" the function in the script editor, Errors like
TypeError: Cannot read property ... from undefined
are thrown. These are not the real errors. This error is only because you ran the function without a event. If your function isn't behaving as expected, You need to figure out the actual error:
To test a trigger function,
Trigger the corresponding event manually: i.e., To test onEdit, edit a cell in sheet; To test onFormSubmit, submit a dummy form response; To test doGet, navigate your browser to the published webapp /exec url.
If there are any errors, it is logged to stackdriver. To view those logs,
In Script editor > Execution icon on the left bar(Legacy editor: View > Executions).
Alternatively, Click here > Click the project you're interested in > Click "Executions" icon on the left bar(the 4th one)
You'll find a list of executions in the executions page. Make sure to clear out any filters like "Ran as:Me" on the top left to show all executions. Click the execution you're interested in, it'll show the error that caused the trigger to fail in red.
Note: Sometimes, The logs are not visible due to bugs. This is true especially in case of webapp being run by anonymous users. In such cases, It is recommended to Switch Default Google cloud project to a standard Google cloud project and use View> Stackdriver logging directly. See here for more information.
For further debugging, You can use edit the code to add console.log(/*object you're interested in*/) after any line you're interested in to see details of that object. It is highly recommended that you stringify the object you're looking for: console.log(JSON.stringify(e)) as the log viewer has idiosyncrasies. After adding console.log(), repeat from Step 1. Repeat this cycle until you've narrowed down the problem.
Congrats! You've successfully figured out the problem and crossed the first obstacle.
2017 Update:
Debug the Event objects with Stackdriver Logging for Google Apps Script. From the menu bar in the script editor, goto:
View > Stackdriver Logging to view or stream the logs.
console.log() will write DEBUG level messages
Example onEdit():
function onEdit (e) {
var debug_e = {
authMode: e.authMode,
range: e.range.getA1Notation(),
source: e.source.getId(),
user: e.user,
value: e.value,
oldValue: e. oldValue
}
console.log({message: 'onEdit() Event Object', eventObject: debug_e});
}
Example onFormSubmit():
function onFormSubmit (e) {
var debug_e = {
authMode: e.authMode,
namedValues: e.namedValues,
range: e.range.getA1Notation(),
value: e.value
}
console.log({message: 'onFormSubmit() Event Object', eventObject: debug_e});
}
Example onChange():
function onChange (e) {
var debug_e = {
authMode: e.authMode,
changeType: changeType,
user: e.user
}
console.log({message: 'onChange() Event Object', eventObject: debug_e});
}
Then check the logs in the Stackdriver UI labeled as the message string to see the output
As an addition to the method mentioned above (Update 2020) in point 4.:
Here is a small routine which I use to trace triggered code and that has saved me a lot of time already. Also I have two windows open: One with the stackdriver (executions), and one with the code (which mostly resides in a library), so I can easily spot the culprit.
/**
*
* like Logger.log %s in text is replaced by subsequent (stringified) elements in array A
* #param {string | object} text %s in text is replaced by elements of A[], if text is not a string, it is stringified and A is ignored
* #param {object[]} A array of objects to insert in text, replaces %s
* #returns {string} text with objects from A inserted
*/
function Stringify(text, A) {
var i = 0 ;
return (typeof text == 'string') ?
text.replace(
/%s/g,
function(m) {
if( i >= A.length) return m ;
var a = A[i++] ;
return (typeof a == 'string') ? a : JSON.stringify(a) ;
} )
: (typeof text == 'object') ? JSON.stringify(text) : text ;
}
/* use Logger (or console) to display text and variables. */
function T(text) {
Logger.log.apply(Logger, arguments) ;
var Content = Stringify( text, Array.prototype.slice.call(arguments,1) ) ;
return Content ;
}
/**** EXAMPLE OF USE ***/
function onSubmitForm(e) {
T("responses:\n%s" , e.response.getItemResponses().map(r => r.getResponse()) ;
}

Custom and first options in ember-power-select

I'm using Ember-power-select-with-create to make custom selections possible in my dropdowns.
This is the power-select part in the .hbs file.
{{#power-select-multiple-with-create
options=options //array for prefill values
selected=offer.offer //is where we save it to (offer is the model and has an array named offer)
onchange=(action (mut offer.offer)) //default onchange for prefill options
onfocus=(action "handleFocus")
onblur=(action "handleBlur")
oncreate=(action "createOffer" offer.offer) //This calls "createOffer"
buildSuggestion=suggestion
as |offer|}}
{{offer}}
{{/power-select-multiple-with-create}}
The "createOffer" function in my .js file looks like this:
It gets two values passed: selected which is offer.offer and searchText which is the input that the user is trying to add.
createOffer(selected, searchText)
{
if (selected == null)
{
selected = []; //This is what I'm currently trying: if its null initialize it
}
if (selected.includes(searchText)) { //Don't add if it's already added
this.get('notify').alert("Already added!", { closeAfter: 4000 });
}
else { // if it's not yet added push it to the array
selected.pushObject(searchText);
}
}
This code works perfectly fine for adding those that we predefined as well for custom options, however it does not work if it is the first and a custom offer that we try to add to a new group of offers.
I'm assuming it has something to do with the fact that the array is not yet initialized. A pointer to the fact that it is due to the array not being initialized is that I get an error message along the lines of: Can't call pushObject on undefined. And I'm assuming the reason that it works with predetermined values is that ember-power-select probably initializes it somewhere but I couldn't find any documentation about it.
Thanks for your answers!
If anyone ever stumbles upon this, this was the solution
Calling that when we create the offer and then initializing the offer array like that:
offer.set('offer', []);

JavaScript error using paper-dropdown-menu

As of adding a paper-dropdown-menu to my Polymer web application I run into the following:
When clicking on the dropdown:
Uncaught TypeError
Polymer.Gestures.findOriginalTarget is not a function
after confirming, followed by:
Cannot set property 'right' of undefined
After confirming again the dropdown shows, albeit a bit out of shape.
What's the problem here ?
The findOriginalTarget does not seem to be set in your version of polymer. Polymer will probably be updated to support it. In the mean time, however, you can download new version of gestures that will add and replace this types of functions.
Download
https://raw.githubusercontent.com/Polymer/polymer/master/src/standard/gestures.html and put it in your polymer folder.
Open paper-dropdown-menu/paper-dropdown-menu.html and add < link rel="import" href="../polymer/gestures.html">
Alternatively, you can find _onTap line at paper-dropdown-menu/paper-dropdown-menu.html and replace function with:
_onTap: function(event) {
//if (Polymer.Gestures.findOriginalTarget(event) === this) {
// this.open();
//}
var targetElement = Polymer.dom(event).localTarget;
if(targetElement === this){
this.open();
}
},
This does work, but I did not test it with touch devices so I can't guarantee that (and I would appreciate feedback on this).
And lastly, if you don't care about _onTap event you could just set it to return false.

Identify which control my application is using

I got a method into my masterpage which populates a value to every label I pass:
function FillLabel(field, text)
{
$(field).html(text);
}
I'll need to make it adaptable to the situation that my field receive an html input and to put the text inside this input I need to use $(field).html(text);
I need to build an if to identify the type of the field and I have no idea how to do that. How can I do this?
You don't give enough details ! According to your code snippet, you seem to talk about JavaScript based on jQuery.
You can test the type of an element with the is() method and selectors :
var element=$(field);
if(element.is(":input")) element.val(text);
else element.html(text);
You can check the tag name:
var tag = $(field).attr('tagName');
edit — #Cédric Belin correctly suggests ".is()":
var isInput = $(field).is(':input');
Much more jQuery-like.
Or check to see if there's a "value" property:
if ('value' in $(field)[0]) { ... }
So, overall:
function FillLabel(field, text) {
var $field = $(field);
if ('value' in $field[0])
$field.val(text);
else
$field.html(text);
}
You might consider using ".text()" instead of ".html()" but I don't know what your application needs are. You also might consider writing this as a jQuery plugin.

Categories

Resources