NicEdit link creation doesn't work in IE 8 and FireFox if text wasn't selected - firefox

I have a problem with nicEdit link creation tool in IE and Firefox.
In general, I think the problem is related to the execCommand in IE and FireFox. It seems document doesn't get updated after execCommand executes.
This is an example of my problem with nicEdit create link command.
if(!this.ln) {
var tmp = 'javascript:nicTemp();';
this.ne.nicCommand("createlink",tmp);
this.ln = this.findElm('A','href',tmp);
// set the link text to the title or the url if there is no text selected
alert(this.ln);
if (this.ln.innerHTML == tmp) {
this.ln.innerHTML = this.inputs['title'].value || url;
};
}
The code above is called when no text is selected, Chrome returns 'javascript:nicTemp()' for the alert(this.ln), while IE 8 and Firefox return 'undefined', so the next line after the alert encounters an error in IE and Firefox.
it seems findElem can't find the newly created link by nicCommand which in turn calls execCommand
I had similar problems when I try to find and modify tags created with execCommand, it seems the dom isn't updated to include them.
Am I right? How can I solve this problem? how can I force the document to be updated ....
please help

my trick for nicEdit, in the situation when no text is selected, is to paste the title given via the Add Link form into the document and select it, then the rest code works as it works when a text is selected.
I used the function pasteHtmlAtCaret described in the following link to paste the title
Insert html at caret in a contenteditable div
this.removePane();
var url = this.inputs.href.value;
var selected = getSelected();
var B= 'javascript:nicTemp()';
if (selected == '')
{
var B = url;
pasteHtmlAtCaret(this.inputs['title'].value || url,true);
}
if(!this.ln){
this.inputs.title.value;this.ne.nicCommand("createlink",B);
this.ln=this.findElm("A","href",B)
}
the getSelected is also a simple function as below
function getSelected()
{
if (document.selection)
return document.selection.createRange().text;
else
return window.getSelection();
}

Ahmad, just use this variation of the "submit" function to avoid the "insert/edit" problem with the link, it worked for me:
submit : function(e) {
var url = this.inputs['href'].value;
if(url == "http://" || url == "") {
alert("Introduce una URL valida para crear el Link.");
return false;
}
this.removePane();
if(!this.ln) {
//**************** YOUR CHANGE WITH A BIT OF VARIATION **************
var selected = this.getSelected();
var tmp = 'javascript:void(0)';
if (selected == '') {
tmp = url;
this.pasteHtmlAtCaret(this.inputs['title'].value || tmp, true);
}
//**************** END OF YOUR CHANGE WITH A BIT OF VARIATION **************
this.ne.nicCommand("createlink",tmp);
this.ln = this.findElm('A','href',tmp);
// set the link text to the title or the url if there is no text selected
if (this.ln.innerHTML == tmp) {
this.ln.innerHTML = this.inputs['title'].value || url;
};
}
if(this.ln) {
var oldTitle = this.ln.title;
this.ln.setAttributes({
href: this.inputs['href'].value,
title: this.inputs['title'].value,
target: '_blank'
});
// set the link text to the title or the url if the old text was the old title
if (this.ln.innerHTML == oldTitle) {
this.ln.innerHTML = this.inputs['title'].value || this.inputs['href'].value;
};
}
}

this.removePane();
var url = this.inputs['href'].value;
var selected = getSelected();
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
var tmp = "";
if(isChrome == true){
tmp=url;
}
else{tmp='javascript:nicTemp()'}
if (selected == '' && isChrome == false)
{
pasteHtmlAtCaret(this.inputs['title'].value || url,true);
}
if (!this.ln) {
//var tmp = this.inputs['title'].value == "" ? this.inputs['href'].value : this.inputs['title'].value;
this.ne.nicCommand("createlink", tmp);
this.ln = this.findElm('A', 'href', tmp);
}
function getSelected()
{
if (document.selection)
return document.selection.createRange().text;
else
return window.getSelection();
}
function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
//create a link format
el.innerHTML = ''+ html +'';
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}

Related

How to show duplicates in a UI when searched in google sheets?

I am developing a tracking system for candidates
Attached a search button.
But I want a UI to pop up which will show the duplicates if present.
And when one of the duplicates is clicked, it will fill the required details in the form
I have made this.
But the results are the first row which matches the search text in B4
function Search()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("Form");
var dataS = ss.getSheetByName("Data");
var str = formS.getRange("B4").getValue();
var values = dataS.getDataRange().getValues();
var valuesFound = false;
for (var i = 0; i < values.length; i++)
{
var rowValue = values[i];
if (rowValue[0] == str) {
formS.getRange("B7").setValue(rowValue[0]) ;
formS.getRange("B9").setValue(rowValue[1]) ;
formS.getRange("B11").setValue(rowValue[2]) ;
formS.getRange("B13").setValue(rowValue[3]) ;
formS.getRange("E7").setValue(rowValue[4]) ;
formS.getRange("E9").setValue(rowValue[5]) ;
formS.getRange("E11").setValue(rowValue[6]) ;
formS.getRange("E13").setValue(rowValue[7]) ;
return;
}
}
if(valuesFound==false){
var ui = SpreadsheetApp.getUi();
ui.alert("No record found!");
}
}
Description
You could get all the first name matches and show them in a dialog, numbered so its easier to pick. Once the user picks the name you can fill out the form.
To use a dropdown and pick a name, that would require a custom dialog. Doable but more complex.
This script is executed from a menu item.
Data
Script
function search() {
try {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let dataS = spread.getSheetByName("Data");
let str = "John";
let values = dataS.getDataRange().getValues();
let rowValue = values.filter( row => row[0] === str );
let ui = SpreadsheetApp.getUi();
let prompt = "";
rowValue.forEach( (row,i) => prompt = prompt.concat((i+1).toString(),": ",row[0], " ",row[1],"\n"));
if( rowValue.length === 0 ) {
ui.alert("Name not found ["+str+"]");
return;
}
else if( rowValue.length > 1 ) {
let response = ui.prompt("Pick a name",prompt,ui.ButtonSet.OK_CANCEL);
if( response.getSelectedButton() == ui.Button.OK ) {
str = response.getResponseText();
str = parseInt(str)-1;
rowValue = rowValue[str];
}
}
else {
rowValue = rowValue[0];
}
ui.alert(rowValue.toString());
// Now you can fill out your form with rowValue
}
catch(err) {
SpreadsheetApp.getUi().alert(err);
}
}
Reference
Array.filter()
Array.forEach()
SpreadsheetApp Ui prompt
Description
So I decided to show how a custom dialog can be used to display a list of names to pick from. First a Ui dialog is displayed to use a filter name. If no name is specified all names will be listed.
Using HTMLService a custom dialog is build using the the pushed variable option for an HTM Template.
Once a name is picked from the list google.script.run is used to return the name to the server and the form can be built from there.
Code.gs
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createMenu("My Menu");
menu.addItem("Test","showTest");
menu.addToUi();
}
function showTest() {
try {
let ui = SpreadsheetApp.getUi();
let response = ui.prompt("What name do you want to search for",ui.ButtonSet.OK_CANCEL);
if( response.getSelectedButton() == ui.Button.OK ) {
var name = response.getResponseText();
if( name === "" ) name = "__All";
}
let spread = SpreadsheetApp.getActiveSpreadsheet();
let dataS = spread.getSheetByName("Data");
let data = dataS.getRange(1,1,dataS.getLastRow(),2).getValues(); // Get range A1:B
if( name !== "__All" ) {
data = data.filter( row => row[0] === name );
}
if( data.length === 0 ) {
ui.alert("No names mathcing ["+name+"] found");
return;
}
let html = HtmlService.createTemplateFromFile('HTML_Test');
html.data = data;
html = html.evaluate();
SpreadsheetApp.getUi().showModalDialog(html,"Show Test");
}
catch(err) {
SpreadsheetApp.getUi().alert(err);
}
}
function pickName(name) {
try {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let dataS = spread.getSheetByName("Data");
dataS.getRange(1,5).setValue(name);
// Build your form here
}
catch(err) {
console.log(err);
}
}
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select id="selectName">
<? for (let i = 0; i < data.length; i++) { ?>
<option><?= data[i][0]+" "+data[i][1] ?></option>
<? } ?>
</select>
<input type="button" onclick="buttonOnClick()" value="Submit">
<script>
function buttonOnClick() {
let name = document.getElementById("selectName").value;
google.script.run.pickName(name);
google.script.host.close();
}
</script>
</body>
</html>
Reference
HTMLService
HTML Template
google.script.run
google.script.host

In Boomla, how can I easily find the next sibling of a file

I'm quite used to nextSiblingand nextElementSibling in the DOM. Is there an easy way of doing a similar thing with Boomla files?
I would need the next sibling within the same placeholder (and null if this is the last), but I'd be interested about finding the next sibling in any placeholder (and null if this is the last file in the last placeholder).
Currently, there is no built-in method for this.
Here are 2 methods for the sjs-4 engine for getting the next in the placeholder or parent:
var nextInBucket = function(f) {
var bucket = f.bucketId();
var bucketSiblings = f.query("../:" + bucket);
var path = f.path();
var index = 0;
var found = false;
bucketSiblings.each(function(t) {
if (t.path() == path) {
found = true;
return false;
}
index++;
});
if ( ! found) {
return null;
}
return bucketSiblings.eq(index + 1);
}
var nextInParent = function(f) {
var parentChildren = f.query("../*");
var path = f.path();
var index = 0;
var found = false;
parentChildren.each(function(t) {
if (t.path() == path) {
found = true;
return false;
}
index++;
});
if ( ! found) {
return null;
}
return parentChildren.eq(index + 1);
}

hide forms tab in a form head crm dynamics 365

I have an entity which contains 2 forms, I want to prevent navagation between these 2 forms based on the value of two option field. In other words if the value of need prescoring is yes navigation is not possible and the inverse, how can I do this ?
Is it possible to simply hide the list ?
Thanks,
No, you cannot dynamically change the forms the user can select. This can only be done statically based on security roles.
Instead I suggest using a single form, where you hide and show the relevant fields/sections/tabs based on the value of your Need Processing field.
You can decide based on your project complexity wrt number of form controls/tabs/sections. We did something like this to maintain & forced navigation based on form control value.
var taskFormOptionSet = {
Form1: 1,
Form2: 2,
};
var FormNames = {
Form1: "Form1",
Form2: "Form2",
};
var myform = Xrm.Page.getAttribute("need_Prescoring").getValue();
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
if (myform == taskFormOptionSet.Form1 && formLabel != FormNames.Form1) {
var items = Xrm.Page.ui.formSelector.items.get();
for (var i in items) {
var form = items[i];
var formId = form.getId();
var formLabel = form.getLabel();
if (formLabel == FormNames.Form1) {
form.navigate();
return;
}
}
}
As it's not supported I used another solution which is to check if the boolean is true and the name of the, if the user tries to change the form he will be redirected to the right form until he changes the value of the boolean.
DiligenceSwitch: function(){
if (Xrm.Page.ui.formSelector.getCurrentItem() != null) {
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
}
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
var kycId = Xrm.Page.data.entity.getId();
SDK.REST.retrieveRecord(kycId, "kyc_Kycdiligence", "kyc_Needprescoring", null, //field for searching the targeted field, entity, targeted field, ...
function (kyc) {
if (kyc != null || kyc.kyc_Needprescoring != null) {
if (formLabel != "Pre-Scoring" && kyc.kyc_Needprescoring == true) {
var windowOptions = { openInNewWindow: false };
var parameters = {};
parameters["formid"] = "4B0C88A9-720C-4BFA-8F59-7C1D5DD84F02";
Xrm.Utility.openEntityForm("kyc_kycdiligence", kycId, parameters, windowOptions);
alert("Vous devez faire le pre-scoring");
}
}
},
function (error) {
Xrm.Utility.alertDialog(error.message);
});
},

gridpanel ext.net communication failure error firefox

I have a ext:gridpanel in my application and we have given the user the ability to arrange columns as per his convenience in the grid.
We also have given a button reset columns to default so that user can go back to the original gridpanel column order.
A method is written in javascript file to bring back the grid to original state when the user clicks "Reset Column to Default button"
The click handler for this button calls the method-"gridpanel_restore"
The code for this method is:-
var gridpanel_restore = function (grid) {
try
{
grid._State = appGlobal.getGridState(grid);
if (grid._State == grid._DefaultState) {
return;
}
grid._State = grid._DefaultState;
var settings = Ext.decode(grid._State);
var cm = grid.getColumnModel();
if (cm.isLocked != null) {
for (var i = cm.columns.length - 1; i > 0; i--) {
if (cm.isLocked(i) && !settings.settings[0].lockField.contains(i)) {
cm.setLocked(i, false, false);
}
}
for (var j = 0; j < settings.settings[0].lockField.length; j++) {
if (!cm.isLocked(i)) cm.setLocked(settings.settings[0].lockField[j], true, false);
}
}
if (settings.settings[0].state.sort) {
}
else {
grid.store.sortInfo = null;
}
grid.applyState(settings.settings[0].state);
var lastColumn = cm.getColumnAt(cm.columns.length - 1);
cm.setColumnWidth(cm.columns.length - 1, lastColumn.width - 1, false);
noMask = true;
CMS.ResetUserSettings(grid._ControlID);
if (settings.settings[0].state.group != null) {
async: false
window.location.href = window.location.href;
}
}
catch (err) {
}
}
This code works perfectly fine in IE but in firefox I get Communication failure on line "window.location.href = window.location.href;" on line 34
I have used this line because the page should be reloaded after setting columns to default otherwsise the grid does not render properly.
I have seen posts related to this but could not find a solution.
Please help. I have already asked this question in ext.net forum but no answer.

How to replace or destroy a tab using the Firefox Add-on SDK?

I did not find anything in the Firefox Add-on SDK (Tab API) that can destroy a tab or replace it with a new tab. I can find the Tab ID, Tab URL, or other identifier. Is there any way to replace or destroy a tab?
Use tab.close(callback).
What do you mean by replace? If you just want to change the URL, then use tab.url = url.
I don't know about SDK, but you can destroy and replace one tab with another tab.
This is how to do it with non-sdk:
How to close a tab by its "id"
var tabIdToClose = 'panel-3-1';
Cu.import('resource://gre/modules/Services.jsm');
var DOMWindows = Services.wm.getEnumerator('navigator:browser');
while (DOMWindows.hasMoreElements()) {
var aDOMWindow = DOMWindows.getNext();
if (aDOMWindow.gBrowser && aDOMWindow.gBrowser.tabContainer) {
var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
for (var i = 0; i < tabs.length; i++) {
var aTab = tabs[i];
var aTabId = aTab.getAttribute('linkedpanel');
console.log('tab id:', aTabId);
if (aTabId == tabIdToClose) {
aDOMWindow.gBrowser.removeTab(aTab);
}
}
} else {
//this window does not have any tabs
}
}
This is how to replace tab with another tab and close the first tab.
var tabIdToReplace = 'panel-3-248';
var tabIdToReplaceWith = 'panel-3-246'; //this tab will be closed, but its contents will be in tabIdToReplace
var aTabToReplace;
var aTabToReplaceWith;
Cu.import('resource://gre/modules/Services.jsm');
var DOMWindows = Services.wm.getEnumerator('navigator:browser');
while (DOMWindows.hasMoreElements()) {
var aDOMWindow = DOMWindows.getNext();
if (aDOMWindow.gBrowser && aDOMWindow.gBrowser.tabContainer) {
var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
for (var i = 0; i < tabs.length; i++) {
var aTab = tabs[i];
var aTabId = aTab.getAttribute('linkedpanel');
console.log('tab id:', aTabId);
if (aTabId == tabIdToReplace) {
aTabToReplace = aTab;
} else if (aTabId == tabIdToReplaceWith) {
aTabToReplaceWith = aTab;
}
if (aTabToReplace && aTabToReplaceWith) {
aTabToReplaceWith.ownerDocument.defaultView.gBrowser.swapBrowsersAndCloseOther(aTabToReplace, aTabToReplaceWith);
break;
}
}
} else {
//this window does not have any tabs
}
}
If you just want to swap the tabs without closing either then do this
I havent completed this so the swap isn't perfect, like I have to set the iconURL and title of the tab that would have been closed: https://gist.github.com/Noitidart/9b335a460f53b0390336

Resources