Unable to delete Mutiple Comp from listbox with Extendscript - extendscript

I can't perform multiple delette from my listbox although I made the listbox mutiselect Why ??
I need your help . You can see the full Script down there.
(function(){
$.win = new Window("palette");
var win = $.win;
win.orientation = "column";
win.alignChildren = ["center", "top"];
win.spacing = 10;
win.margins = 16;
var listbox1 = win.add("listbox", undefined, undefined, { name: "listbox1", multiselect: true, columnTitles: "Max", showHeaders: true });
listbox1.preferredSize.width = 136;
listbox1.preferredSize.height = 208;
var button1 = win.add("button", undefined, undefined, { name: "button1" });
button1.text = "Search";
var button2 = win.add("button", undefined, undefined, { name: "button2" });
button2.text = "Delete";
win.show();
var myNewArray = [];
button1.onClick = function Search() {
var compsArray = new Array();
var myProj = app.project;
myNewArray = [];
listbox1.removeAll();
for (var i = 1; i <= myProj.numItems; i++) {
if (myProj.item(i) instanceof CompItem) {
myNewArray = compsArray[compsArray.length] = myProj.item(i);
listbox1.add("item", myNewArray.name);
}
}
}
button2.onClick = function deletecomps() {
for (var s = 1; s <= app.project.numItems; s ++) {
if ((app.project.item(s) instanceof CompItem) && (app.project.item(s).name.match(listbox1.selection))) {
myComp = app.project.item(s);
break;
}
}
app.project.item(s).remove ();
}
})();
You can see an image to clarify the script in AE

Your problem is that listbox1.selection in line 34
if ((app.project.item(s) instanceof CompItem) && (app.project.item(s).name.match(listbox1.selection))) {
is an array, and you're trying to match it to a string returned by app.project.item(s).name which is never going to match.
Also, what are you trying to achieve with the lines
myComp = app.project.item(s);
break;
Here's the onClick function, but it works. It loops through the selection, and looks for a matching project item, based on the text of the listbox matching the comp's name. This is dangerous, because identical comp names would create false positives. I strongly suggest you don't use this technique in production code, because it will definitely cause problems for your users.
Also I'd turn the part wherre you populate the list into a separate function, and call it after you click delete, so that the list is refreshed, because at the moment the list stays the same, even after the comp is deleted.
button2.onClick = function deletecomps() {
for (var b= 0; b < listbox1.selection.length; b++){
for (var s = 1; s <= app.project.numItems; s ++) {
if ((app.project.item(s) instanceof CompItem) && (app.project.item(s).name.match(listbox1.selection[b].text))) {
app.project.item(s).remove ();
}
}
}
}

Related

How to change the default values when add link Sharepoint 2013

In Add Link page, is it possible to change the default values like title, address, show these links to, by using URL parameters?
According to this, it seems possible in sharepoint2010. Does anyone know whether it works in 2013??
If not, is it possible to add a link by post REST API??
This problem can be solved by the steps below.
Add a custom action. Just follow the steps here.
In my case code is as below
SP.SOD.executeFunc("callout.js", "Callout", function() {
var itemCtx = {};
itemCtx.Templates = {};
itemCtx.BaseViewID = 'Callout';
// Define the list template type
itemCtx.ListTemplateType = 101;
itemCtx.Templates.Footer = function(itemCtx) {
// context, custom action function, show the ECB menu (boolean)
return CalloutRenderFooterTemplate(itemCtx, AddCustomAction, true);
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
});
function AddCustomAction(renderCtx, calloutActionMenu) {
// Add your custom action
calloutActionMenu.addAction(new CalloutAction({
text: "FAVORITE",
// tooltip: 'This is your custom action',
onClickCallback: function() {
CreateCustomNewQuickLink(renderCtx.CurrentItem.FileLeafRef, renderCtx.CurrentItem.FileRef);
}
}));
// Show the default document library actions
CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu);
}
function CreateCustomNewQuickLink(title, url) {
var urlAddress = $(location).attr('protocol') + "//" + $(location).attr('host') + '/_Layouts/quicklinksdialogformTEST.aspx?Mode=Link' +
'&title=' + encodeURIComponent(title) +
'&url=' + encodeURIComponent(url);
ShowNewQuicklinkPopup(urlAddress, PageRefreshOnDialogClose);
}
Create a new add link page which is copied from "quicklinksdialogform.aspx". I add some javascript as below.
$(init)
function init() {
var args = new Object();
args = GetUrlParms();
if (args["title"] != undefined) {
$(".ms-long")[0].value = decodeURIComponent(args["title"]);
}
if (args["url"] != undefined) {
$(".ms-long")[1].value = decodeURIComponent(args["url"]);
}
}
function GetUrlParms() {
var args = new Object();
var query = location.search.substring(1);
var pairs = query.split("&");
for (var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if (pos == -1) continue;
var argname = pairs[i].substring(0, pos);
var value = pairs[i].substring(pos + 1);
args[argname] = unescape(value);
}
return args;
}
It works like below

Chrome extension replaces letters, but breaks certain pages

I used the following TreeWalker as a template from this post https://stackoverflow.com/a/37178130/7102491 and modified it to skip the element 'script', to prevent certain pages like a google search from breaking to no avail. Does anyone know how I can change the code to prevent breaking certain pages? Thanks.
var replaceArry = [
[/b/gi, 'better'],
[/Terms of service/gi, 'Términos y condiciones'],
[/Privacy policy/gi, 'Privacidad'],
// etc.
];
var numTerms = replaceArry.length;
var txtWalker = document.createTreeWalker (
document.body,
NodeFilter.SHOW_TEXT,
{ acceptNode: function (node) {
//-- Skip whitespace-only nodes
if (node.nodeValue.trim() && node.parentNode.nodeName != 'SCRIPT')
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
}
},
false
);
var txtNode = null;
while (txtNode = txtWalker.nextNode () ) {
var oldTxt = txtNode.nodeValue;
for (var J = 0; J < numTerms; J++) {
oldTxt = oldTxt.replace (replaceArry[J][0], replaceArry[J][1]);
}
txtNode.nodeValue = oldTxt;
}

How to iterate in Group in Phaser.js

I have create a group in phaserjs
this.fruitsOutline = this.game.add.group();
After that I have added few sprites in it. Everything is working correctly. Now if want to access this.fruitsOutline, from inside of a onDragStart event handler, it is giving undefined
var GameState = {
init:function(){
this.physics.startSystem(Phaser.Physics.ARCADE);
},
create: function () {
var innerImgPos = {x:150,y:200};
var outlineImgPos = {x:460,y:200};
var FIXED_DISTANCE_Y = 150;
var gameData = [
//...some data
];
this.background = this.game.add.sprite(0, 0, 'background');
this.overlapHappen = false;
this.startPos = {x:150,y:197};
this.fruitsOutline = this.game.add.group();
this.fruitsInner = this.game.add.group();
for(var i=0; i<gameData.length; i++){
fruitOuter = this.fruitsOutline.create(outlineImgPos.x,((outlineImgPos.y+25)*i)+FIXED_DISTANCE_Y,gameData[i].fruit_outline.img);
fruitOuter.name = gameData[i].fruitName;
fruitOuter.anchor.setTo(.5);
fruitOuter.customParams = {myName:gameData[i].fruit_outline.name};
this.game.physics.arcade.enable(fruitOuter);
fruitOuter.body.setSize(100,100,50,50);
fruitInner = this.fruitsInner.create(innerImgPos.x,((innerImgPos.y+25)*i)+FIXED_DISTANCE_Y,gameData[i].fruit_inner.img);
fruitInner.name = gameData[i].fruitName;
fruitInner.anchor.setTo(0.5);
fruitInner.inputEnabled = true;
fruitInner.input.enableDrag();
fruitInner.input.pixelPerfectOver = true;
fruitInner.originalPos = {x:fruitInner.position.x,y:fruitInner.position.y};
this.game.physics.arcade.enable(fruitInner);
fruitInner.body.setSize(100,100,50,50);
fruitInner.customParams = {myName:gameData[i].fruit_inner.name,targetKey:fruitOuter,targetImg:gameData[i].fruit_outline.name};
fruitInner.events.onDragStart.add(this.onDragStart);
fruitInner.events.onDragStop.add(this.onDragStop,this);
}
},
update: function () {
},
onDragStart:function(sprite,pointer){
console.log(this.fruitsInner) //this gives undefined I expect an array
},
onDragStop:function(sprite,pointer){
var endSprite = sprite.customParams.targetKey;
console.log(endSprite);
this.stopDrag(sprite,endSprite)
},
stopDrag:function(currentSprite,endSprite){
var currentSpriteRight = currentSprite.position.x + (currentSprite.width / 2);
if (!this.game.physics.arcade.overlap(currentSprite, endSprite, function() {
var currentSpriteTarget = currentSprite.customParams.targetImg;
var endSpriteName = endSprite.customParams.myName;
console.log(currentSpriteTarget,endSpriteName);
if(currentSpriteTarget === endSpriteName){
currentSprite.input.draggable = false;
currentSprite.position.copyFrom(endSprite.position);
currentSprite.anchor.setTo(endSprite.anchor.x, endSprite.anchor.y);
}
console.log(currentSprite.width);
})) {
//currentSprite.position.copyFrom(currentSprite.originalPosition);
currentSprite.position.x = currentSprite.originalPos.x;
currentSprite.position.y = currentSprite.originalPos.y;
}
},
render:function(){
game.debug.body(this.fruitsInner);
//game.debug.body(this.orange_outline);
}
}
You're missing the context when adding the drag callback.
Try that (adding this as the second argument):
fruitInner.events.onDragStart.add(this.onDragStart, this);
Oh, and inside the callback (or anywhere in the state) this.fruitsInner will be an instance of Phaser.Group, not an array like that comment says. The array you're looking for is probably this.fruitsInner.children.

SP.NavigationNode.get_isVisible() broken?

I need to read the "Top Nav", the "Children Nodes" and check if each node is visible.
I am using JSOM to accomplish this. Everything is working fine except for the get_isVisible() function. It always returns true. MSDN: http://msdn.microsoft.com/en-us/library/office/jj246297.aspx
I am on a publishing site in 2013 and I know some of the items are hidden. (My web and context are defined outside of this snippet)
var visParents = [], visChildren = [];
var topNodes = web.get_navigation().get_topNavigationBar();
context.load(topNodes);
context.executeQueryAsync(onQuerySucceeded, onQueryFailed)
function onQuerySucceeded() {
var nodeInfo = '';
var nodeEnumerator = topNodes.getEnumerator();
while (nodeEnumerator.moveNext()) {
var node = nodeEnumerator.get_current();
nodeInfo += node.get_title() + '\n';
if (node.get_isVisible())
visParents.push(node);
}
console.log("Current nodes: \n\n" + nodeInfo);
console.log("Visible Parents", visParents)
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
It is a known issue, it seems that SP.NavigationNode.isVisible property does not correspond to the property that indicates whether navigation node is hidden or shown.
Please refer "Hidden" property of SPNavigationNode for a details
The following function demonstrates how to retrieve hidden node Urls:
function getGlobalNavigationExcludedUrls(Success,Error)
{
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var subwebs = web.get_webs();
var pagesList = web.get_lists().getByTitle("Pages");
var pageItems = pagesList.getItems(SP.CamlQuery.createAllItemsQuery());
var allProperties = web.get_allProperties();
context.load(web);
context.load(subwebs);
context.load(allProperties);
context.load(pageItems);
context.executeQueryAsync(
function() {
var excludedIds = allProperties.get_item('__GlobalNavigationExcludes').split(';');
var exludedUrls = [];
for (var i = 0; i < excludedIds.length - 1; i++ )
{
for (var j = 0; j < subwebs.get_count(); j++ )
{
var subweb = subwebs.getItemAtIndex(j);
if(subweb.get_id().toString() == excludedIds[i]){
exludedUrls.push(subweb.get_serverRelativeUrl());
break;
}
}
for (var j = 0; j < pageItems.get_count(); j++ )
{
var pageItem = pageItems.getItemAtIndex(j);
if(pageItem.get_item('UniqueId').toString() == excludedIds[i]){
exludedUrls.push(web.get_serverRelativeUrl() + pageItem.get_item('FileRef'));
break;
}
}
}
Success(exludedUrls);
},
Error
);
}
//Usage: print excluded nodes Urls
getGlobalNavigationExcludedUrls(function(excludedNodeUrls){
for (var j = 0; j < excludedNodeUrls.length; j++ )
{
console.log(excludedNodeUrls[j]);
}
},
function(sender,args){
console.log(args.get_message());
});

Dropdown field - first item should be blank - For more than one field (Sharepoint)

I was looking for a solution to the problem of getting a blank default when using a lookup in a field in Sharepoint. Kit Menke's solution to "Dropdown field - first item should be blank" question works perfectly for my first field with a lookup. But I can't make it work if have more that one field in the same list where I need to insert a blank for each lookup field (works only for the first field). I tried adding a new "Web Part" and applying the same code to the second field, but doesn't work. Any ideas? Thanks in advance
Follow-up to my answer here: Dropdown field - first item should be blank
Version 2.0 allows you to add the names of your dropdowns to dropdownNames in the MyCustomExecuteFunction function. As with the first one, this will work only with required single select lookup fields. Also, in order to edit the page again and update your Content Editor Web Part you may have to choose a value for your dropdowns otherwise you get the dreaded An unexpected error has occurred.. Good luck! :D
<script type="text/javascript">
function GetDropdownByTitle(title) {
var dropdowns = document.getElementsByTagName('select');
for (var i = 0; i < dropdowns.length; i++) {
if (dropdowns[i].title === title) {
return dropdowns[i];
}
}
return null;
}
function GetOKButtons() {
var inputs = document.getElementsByTagName('input');
var len = inputs.length;
var okButtons = [];
for (var i = 0; i < len; i++) {
if (inputs[i].type && inputs[i].type.toLowerCase() === 'button' &&
inputs[i].id && inputs[i].id.indexOf('diidIOSaveItem') >= 0) {
okButtons.push(inputs[i]);
}
}
return okButtons;
}
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value',value);
if (typeof(optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option,options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
oDropdown.options.selectedIndex = 0;
}
function WrapClickEvent(element, newFunction) {
var clickFunc = element.onclick;
element.onclick = function(event){
if (newFunction()) {
clickFunc();
}
};
}
function MyCustomExecuteFunction() {
// **** ADD YOUR REQUIRED SINGLE SELECT FIELDS HERE ***
var dropdownNames = [
'Large Lookup Field',
'My Dropdown Field'
];
var dropdownElements = [];
for (var d = 0; d < dropdownNames.length; d++) {
// find the dropdown
var dropdown = GetDropdownByTitle(dropdownNames[d]);
// comment this IF block out if you don't want an error displayed
// when the dropdown can't be found
if (null === dropdown) {
alert('Unable to get dropdown named ' + dropdownNames[d]);
continue;
}
AddValueToDropdown(dropdown, '', '', 0);
// collect all of our dropdowns
dropdownElements.push(dropdown);
}
// add a custom validate function to the page
var funcValidate = function() {
var isValid = true;
var message = "";
for (var d = 0; d < dropdownElements.length; d++) {
if (0 === dropdownElements[d].selectedIndex) {
// require a selection other than the first item (our blank value)
if (isValid) {
isValid = false;
} else {
message += "\n"; // already had one error so we need another line
}
message += "Please choose a value for " + dropdownNames[d] + ".";
}
}
if (!isValid) {
alert(message);
}
return isValid;
};
var okButtons = GetOKButtons();
for (var b = 0; b < okButtons.length; b++) {
WrapClickEvent(okButtons[b], funcValidate);
}
}
_spBodyOnLoadFunctionNames.push("MyCustomExecuteFunction");
</script>
How about prepending a null option to the select menu of sharepoint.Like,
$('#idOfSelectMenu').prepend('<option value="" selected>(None)</option>');
I used this approach and append this code only in the NewForm.aspx because in EditForm.aspx it will override the selected option.

Resources