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

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

Related

Keeping Data between refreshes in Blazor server

I have a multiple page Web Application that needs to be refreshed after a user has entered in data to then display the data on the table. I have Scoped dependencies so my users do not see the same data table as they are unique to each user. After they enter the data and the page refreshes the page goes blank and the scope is empty. How would I go about keeping the data from the scopes after refresh? I essentially needs a Singlton dependency that isn't shared between users. This is a Blazor Server Side Application. EDIT: Accept Button Method
if (Controlled_Variables.Attendance != null)
{
if (_JBS.CheckFields(_JBF.JobID, _JBF.WorkCenter, _JBF.SetupRun) == false)
{
string prompted = await jsRunTime.InvokeAsync<string>("alert", "Please Verify Job ID, Work Center, and Setup/Run are selected!");
}
else
{
FilledOut = true;
_JBF.transactionData = Guid.NewGuid();
_JBF.jobOperationID = _JBF.WorkCenter;
DateTime recordDate = DateTime.Now;
JobOperationRecord JOR = await _JBS.GetJobOperationRecordByOperationID(_JBF.WorkCenter);
WorkCenterRecord SingleWorkCenter = await _JBS.GetWorkCenterInformation(JOR.Work_Center);
EmployeeRecord Employee = await _JBS.GetEmployeeRecord(Controlled_Variables.Employee_ID);
try
{
if (Check.IsThisAnActiveJob(_JBF.JobID))
{
bool Complete = await First_Article_Complete(_JBF.jobOperationID, _JBF.SetupRun);
if (Complete)
{
Controlled_Variables.Sessions.Clear();
Controlled_Variables.Sessions = await _JBS.GetOpenJobOperationTimeSessionForUser(Controlled_Variables.Employee_ID);
bool activeNonGhostSession = false;
foreach (JobOperationSessionManager Session in Controlled_Variables.Sessions)
{
if (Session.ghost == "Y")
{
Controlled_Variables.ActiveSession = Session;
activeNonGhostSession = true;
}
}
_JBS.UpdateJobOperationStatus(JOR.Job_Operation.ToString(), JOR.Status == "C" ? "C" : "S");
if (!activeNonGhostSession && !_JBF.GhostedCheck)
{
_JBS.AddNewJobOperationTimeSessionForUser(Controlled_Variables.Employee_ID, "N", _JBF.transactionData.ToString(), JOR.Work_Center,
_JBF.jobOperationID, _JBF.JobID, recordDate.ToString("yyyy-MM-dd HH:mm:ss"), _JBF.jobOperationTime.ToString(), _JBF.SetupRun);
_JBF.sessionManagerCreated = true;
_JBS.InsertIntoTransactionDetail_NewEntry_JobOperation(_JBF.transactionData.ToString(), _JBF.jobOperationID, _JBF.jobOperationTime.ToString(),
JOR.Work_Center, _JBF.JobID);
_JBF.transDetailCreated = true;
_JBS.InsertIntoTransactionData_NewEntry_JobOperation(_JBF.transactionData.ToString(), Controlled_Variables.Employee_ID, recordDate.ToString());
_JBF.transDataCreated = true;
_JBS.InsertIntoJobOperationTime_NewEntry_JobOperationStart(_JBF.jobOperationID, Controlled_Variables.Employee_ID, recordDate.ToString(),
Employee.Hourly_Rate.ToString(), SingleWorkCenter.Labor_Burden.ToString(), SingleWorkCenter.Machine_Burden.ToString(), SingleWorkCenter.GA_Burden.ToString(),
_JBF.jobOperationTime.ToString(), JOR.Work_Center, _JBF.jobOperationTimeObjectID.ToString(), JOR.ObjectID.ToString(), Employee.ObjectID.ToString());
_JBF.jobOperationTimeCreated = true;
btnStartJob = true;
btnStopJob = false;
NavManage.NavigateTo(NavManage.Uri, forceLoad: true);
string prompted = await jsRunTime.InvokeAsync<string>("alert", "The job has been entered successfully.", "ERROR");
Sorry for the confusion for the use of refresh. I needed to reload the table to allow the data put in by users to be visable after they hit accept. To do this I added a navigation manager
NavManage.NavigateTo(NavManage.Uri, forceLoad: true);
Which force loads the page and displays the new data. If there may be another way to do this to keep the scope I am open to using a different method. As you can see I have tried to just recall the method in which the table data is loaded into to possibly get the new data populated but then the application never reiterates the loop to actually display the data on the page
#for (int i = 0; i < Controlled_Variables.TransactionData.Count; i++)
{
var TransacData = Controlled_Variables.TransactionData[i];
TransacData.index = i;
#for (int l = 0; l < Controlled_Variables.TransactionDetail.Count; l++)
{
var transacdetail = Controlled_Variables.TransactionDetail[l];
transacdetail.index = l;
TransactionDetailRecord selectData = Controlled_Variables.TransactionDetail[l];
#if (transacdetail.Transaction_Data == TransacData.Transaction_Data)
{
<div><input value="#selectData" type="radio" name="Select" onclick="#(() => ShowSelectedRecord(selectData, TransacData))"> </div>
<div>#transacdetail.Target_Integer</div>
<div>#transacdetail.Job</div>
<div>#Controlled_Variables.Job.Part_Number</div>
<div>#TransacData.Transaction_Start</div>
if (TransacData.Transaction_Type == 10)
{
<div>#TransacData.Transaction_Type</div>
btnStartJob = true;
btnStopJob = false;
}
else
{
<div>#TransacData.Transaction_Type</div>
btnStartJob = false;
btnStopJob = true;
}
<div>#Controlled_Variables.Job.Customer</div>
<div>#transacdetail.Work_Center</div>
<div>#transacdetail.Quantity</div>
<div>#TransacData.Transaction_End</div>
<div>#transacdetail.Entry_Type</div>
<div>#transacdetail.Labor_Hrs</div>
<div>#transacdetail.Machine_Hrs</div>
<div>#TransacData.Transaction_Data</div>
<div>#transacdetail.Transaction_Detail</div>
}
}
}

Set the sourceRange of Data Validation to an array of values

I'm creating a social media outreach tracker. I want to create a drop-down list of the contact name. The problem is that I have two sources of names on two different sheets.
I wrote a script that pulls the names from the two different sources and combines them to a single array.
I was hoping to set the source range as that array.
Here is my code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var auditionsSheet = SpreadsheetApp.getActiveSpreadsheet();
var castingDirectorsTab = auditionsSheet.getSheetByName("Casting Directors");
var contactsTab = auditionsSheet.getSheetByName("Contacts");
var socialMediaOutreachTab = auditionsSheet.getSheetByName("Social Media Outreach");
var lastRowCD = castingDirectorsTab.getLastRow();
var lastRowContacts = contactsTab.getLastRow();
var activeCell = socialMediaOutreachTab.getActiveCell();
var activeColumn = activeCell.getColumn();
// get data
var castingDirectorNameData = castingDirectorsTab.getRange(2, 1, lastRowCD, 1).getValues();
var contactNameData = contactsTab.getRange(2, 1, lastRowContacts, 1).getValues();
//get name data to a single arrays
var castingDirectorName = [];
castingDirectorNameData.forEach(function(yr) {
castingDirectorName.push(yr[0]);
});
var contactName = [];
contactNameData.forEach(function(yr) {
contactName.push(yr[0]);
});
// get rid of the empty bits in the arrays
for (var x = castingDirectorName.length-1; x > 0; x--) {
if ( castingDirectorName[x][0] === undefined ) {
castingDirectorName.splice( x, 1 )
}
}
for (var x = contactName.length-1; x > 0; x--) {
if ( contactName[x][0] === undefined ) {
contactName.splice( x, 1 )
}
}
//combine two data sources for data validation
var combinedNames = [];
combinedNames.push(castingDirectorName + contactName);
Logger.log (combinedNames);
Logger.log( typeof combinedNames);
// data validation set up and build
if (activeColumn == 1 && auditionsSheet.getName() == "Social Media Outreach") {
var range = auditionsSheet.getRange(activeCell.getRow(), activeColumn +1);
var sourceRange = combinedNames;
setDataValid_(range, sourceRange)
}
}
When I enter a date in Col A on Social Media Outreach, nothing happens in Col 2.
I was using an existing working nested data validation script I have but the sourceRange pulls from a sheet based on the value in the active cell. Here is that code:
function setDataValid_(range, sourceRange) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sourceRange, true)
.build();
range.setDataValidation(rule);
}
function onEdit() {
var aSheet = SpreadsheetApp.getActiveSheet();
var aCell = aSheet.getActiveCell();
var aColumn = aCell.getColumn();
// data validation for Auditions Tab Projet Type to Project Details
if (aColumn == 9 && aSheet.getName() == 'Auditions') {
var range = aSheet.getRange(aCell.getRow(), aColumn + 1);
var sourceRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('RefTables!' + aCell.getValue())
setDataValid_(range, sourceRange)
}
}
For this script when I select from the data validation drop-down, a new data validation comes up in the next col with the appropriate secondary data validation.
So the question is, can the source range be set to an array or do I need to put the names back into my sheet to reference a la the second script.
I've looked through the documentation and searched and can't find an answer. I'm relatively new to GAS and am not sure of all the inner workings of the data validation builder.

Ajax validation callout extender with Behaviour ID validation

I have defined Ajaxvalidatoncalloutextender control with unique behaviour ID in my page for all the page controls.
<ajaxToolkit:ValidatorCalloutExtender ID="vceNotProgress" runat="server" TargetControlID="revInvalidNotClosedProgressValue" BehaviorID="b_vceNotProgress">
</ajaxToolkit:ValidatorCalloutExtender>
<ajaxToolkit:ValidatorCalloutExtender ID="vceProgress" runat="server" TargetControlID="revInvalidClosedProgressValue" BehaviorID="b_vceProgress">
</ajaxToolkit:ValidatorCalloutExtender>
I'm validating on client click of submit button like this
function ValidatePage()
{
if (typeof (Page_Validators) == "undefined") return;
var noOfValidators = Page_Validators.length;
var Page_Callout = new Array(2);
Page_Callout[0] = "b_vceNotProgress"; -- behaviour ID
Page_Callout[1] = "b_vceProgress"; -- behaviour ID
for (var validatorIndex = 0; validatorIndex < noOfValidators; validatorIndex++) {
var validator = Page_Validators[validatorIndex];
ValidatorValidate(validator);
if (!validator.isvalid) {
showValidatorCallout($find(Page_Callout[validatorIndex]));
return false;
}
}
return true;
}
My Problem: I donot want to hardcode the array like Page_Callout[0],Page_Callout[1]. I need to populate the array based
on the visible controls (i.e assign behaviour ID) in the page.
if (typeof (Page_Validators) == "undefined") return;
var noOfValidators = Page_Validators.length;
var count = 0;
var Page_Callout = [];
for (var i = 0; i < Page_Validators.length; i++) {
Page_Callout[Page_Callout.length++] = Page_Validators[i]._behaviors != null ? Page_Validators[i]._behaviors[0]._id : "";
count++;
}
for (var validatorIndex = 0; validatorIndex < noOfValidators; validatorIndex++) {
var validator = Page_Validators[validatorIndex];
ValidatorValidate(validator);
if (!validator.isvalid) {
showValidatorCallout($find(Page_Callout[validatorIndex]));
return false;
}
}
return true;
}
function hideValidatorCallout() {
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
}
function showValidatorCallout(currrentCallout) {
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout = currrentCallout;
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.show(true);
}

Set selection on tekst inside CKEditor

I'm having trouble to select text in CKEditor(3.6). As we use plain text i dont know how to use correctly the range selectors.
HTML code of the CKEditor:
<body spellcheck="false" class="rf-ed-b" contenteditable="true">
<br>
Cross those that apply:<br>
<br>
<br>
[«dummy»] If he/she is tall<br>
<br>
[«dummy»] If he/she is a male<br>
<br>
[«dummy»] If he/shi is a minor<br>
<br>
Specialties:<br>
<br>
[«dummy»] «Write here the specialties if known»<br>
<br>
<br>
«You are now done with filling in this form»<br>
</body>
With the keys 'CRTL+N' I want to go to the next filleble spot:
«[label]»
I tried stuff like:
var editor = CKEDITOR.instances['MyEditor'];
var findString = '«';
var element = editor.document.getBody();
var ranges = editor.getSelection().getRanges();
var startIndex = element.getHtml().indexOf(findString);
if (startIndex != -1) {
ranges[0].setStart(element.getFirst(), startIndex);
ranges[0].setEnd(element.getFirst(), startIndex + 5);
editor.getSelection().selectRanges([ranges[0]]);
}
Error:
Exception: Index or size is negative or greater than the allowed amount
While totally stripepd down it kinda works a bit:
var editor = CKEDITOR.instances['MyEditor'];
var ranges = editor.getSelection().getRanges();
var startIndex = 10;
if (startIndex != -1) {
ranges[0].setStart(element.getFirst(), startIndex);
ranges[0].setEnd(element.getFirst(), startIndex + 5);
editor.getSelection().selectRanges([ranges[0]]);
}
here it selects 5th till 10th char on first row.
I used the following sources:
example on Stackoverflow
Another stackoverflow example
CKEditor dom selection API
All solutions i can find work with html nodes.
How can set selection range on the '«' till next '»'
I've managed to solve this solution. Meanwhile i also upgraded CKeditor to 4.0.
This shouldnt have an impact on the solution.
It is a lot of code in JS.
On my keybinding i call the following JS function: getNextElement()
In this solution it also searches behind the cursor, this makes it possible to step through multiple find results.
Also the view gets scrolled to the next search result
var textNodes = [], scrollTo=0,ranges = [];
function getNextElement(){
var editor =null;
ranges = [];
// I dont know the ID of the editor, but i know there is only one the page
for(var i in CKEDITOR.instances){
editor = CKEDITOR.instances[i];
}
if(editor ==null){
return;
}
editor.focus();
var startRange = editor.getSelection().getRanges()[0];
var cursorData ="",cursorOffset=0,hasCursor = false;
if(startRange != null && startRange.endContainer.$.nodeType == CKEDITOR.NODE_TEXT){
cursorOffset = startRange.startOffset;
cursorData = startRange.endContainer.$.data;
hasCursor = true;
}
var element;
element = editor.document.getBody().getLast().getParent();
var selection = editor.getSelection();
// Recursively search for text nodes starting from root.
textNodes = [];
getTextNodes( element );
var foundElement = false;
foundElement = iterateEditor(editor,hasCursor,cursorData,cursorOffset);
if(!foundElement){
foundElement =iterateEditor(editor,false,"",0);
}
if(foundElement){
// Select the range with the first << >>.
selection.selectRanges( ranges );
jQuery(".cke_wysiwyg_frame").contents().scrollTop(scrollTo);
}
}
function iterateEditor(editor,hasCursor,cursorData,cursorOffset){
var foundElement = false;
var rowNr = 0;
var text, range;
var foundNode = false;
if(!hasCursor){
foundNode = true;
}
// Iterate over and inside the found text nodes. If some contains
// phrase "<< >>", create a range that selects this word.
for (var i = textNodes.length; i--; ) {
text = textNodes[ i ];
if ( text.type == CKEDITOR.NODE_ELEMENT && text.getName() == "br" ){
rowNr++;
} else if ( text.type == CKEDITOR.NODE_TEXT ) {
var sameNode = false;
if(text.$.data == cursorData){
foundNode = true;
sameNode = true;
}
if(foundNode){
var startIndex = -1;
var endIndex = 1;
if(sameNode){
// Check inside the already selected node if the text has multiple hits on the searchphrase
var indicesStart = getIndicesOf('\u00AB', text.getText());
var indicesEnd = getIndicesOf('\u00BB', text.getText());
for (var j = indicesStart.length; j--; ) {
if(indicesStart[j] > cursorOffset){
startIndex = indicesStart[j];
endIndex = indicesEnd[j];
}
}
} else{
startIndex = text.getText().indexOf( '\u00AB' );
endIndex = text.getText().indexOf( '\u00BB' );
}
if ( startIndex > -1 && (!sameNode || startIndex > cursorOffset)) {
range = editor.createRange();
range.setStart( text, startIndex );
foundElement = true;
// calculate the height the window should scroll to focus the selected element
scrollTo = (rowNr)*20;
}
if ( endIndex > -1 && foundElement ) {
range.setEnd( text, endIndex+1 );
ranges.push( range );
return true;
}
}
}
}
}
function getIndicesOf(searchStr, str) {
var startIndex = 0, searchStrLen = searchStr.length;
var index, indices = [];
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
function getTextNodes( element ) {
var children = element.getChildren(), child;
for ( var i = children.count(); i--; ) {
child = children.getItem( i );
textNodes.push( child );
}
}

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

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);
}
}

Resources