8

I have implemented a feature that once activated adds a heading called Home, and a link underneath to a NewForm.aspx like such:

// Add Home node
var mainListsNode = new SPNavigationNode("Home", web.Url, true);
leftNav.AddAsFirst(mainListsNode);

// Add NewForm link
node = new SPNavigationNode("Add New Item", string.Format("{0}/Lists/CustomList/NewForm.aspx", web.Url), true);
homeNode.Children.AddAsLast(node);

My requirement is now to make that link pop open the modal dialog box instead. I achieved this easily in my webpart where I can use JavaScript like this:

<a href="#" onclick="javascript:openDialog();return false;" target="_self">

function openDialog() {
    var options = {
        url: '/sites/TESTSITE/Lists/CustomList/NewForm.aspx?IsDlg=1',
        title: "Add New Item",
        dialogReturnValueCallback: itemNotificationSent,
        allowMaximize: false
    };
    SP.UI.ModalDialog.showModalDialog(options);

How can I achieve this in my first example? Bonus points for advising me how I can also add my dialogReturnValueCallback as my second example:

function itemNotificationSent(dialogResult, returnValue) {
    if (dialogResult == SP.UI.DialogResult.OK) {
        SP.UI.Notify.addNotification('An Item was added. Thank you!');
    }

    else {
        SP.UI.Notify.addNotification('The "Item Add" was cancelled...');
        return false;
    }
}

1 Answer 1

4

By default, sharepoint uses AspMenu as control that renders top nav and quick lunch. Something interesting you can find using reflector in this control. Consider method OnMenuItemDataBound (some code omitted for clarity):

if (bool.TryParse(dataItem["AllowScriptUrl"], out result) && result)
{
    if (this.allowScriptUrlItems == null)
    {
        this.allowScriptUrlItems = new Dictionary<MenuItem, bool>();
    }
    this.allowScriptUrlItems.Add(e.Item, true);
}  

where dataItem is a SiteMapNode object. And another peace of code, from BuildDefaultInnerItem method:

if (((item != null) && item.Enabled) && (!string.IsNullOrEmpty(navigateUrl) || item.Selectable))
{
    if (!string.IsNullOrEmpty(navigateUrl))
    {
        if (navigateUrl.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase))
        {
            if (this.allowScriptUrls || ((this.allowScriptUrlItems != null) && this.allowScriptUrlItems.ContainsKey(item)))
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Href, navigateUrl, false);
            }
        }

SPNavigationNode class has Properties, that mapped to dataItem. Hmmm, it seems that this code should work:

var leftNav = web.Navigation.QuickLaunch;
var mainListsNode = new SPNavigationNode("jslink", "javascript:alert('hi there!')", true);
leftNav.AddAsFirst(mainListsNode);
mainListsNode.Properties["AllowScriptUrl"] = "true";
mainListsNode.Update();  

..and it actually works! This code produces this html markup:

<a href="javascript:alert('hi there!')" class="static menu-item">
    <span class="additional-background">
       <span class="menu-item-text">jslink</span>
    </span>
</a>

So, you can put your javascript on masterpage, and call required functions using above technique.
For example, something like this:

var leftNav = web.Navigation.QuickLaunch;
var mainListsNode = new SPNavigationNode("jslink", "javascript:mycoolfunc('" + web.Title + "')", true);
leftNav.AddAsFirst(mainListsNode);
mainListsNode.Properties["AllowScriptUrl"] = "true";
mainListsNode.Update();  

and js:

function mycoolfunc(param){
    alert(param);
    }

note: you should always call SPNavigationNode constuctor with 3 arguments and true as 3rd, failing that you got an exception (The specified url does not exist in the site collection...).

UPDATE

My experiments revealed that this lines are redundant

mainListsNode.Properties["AllowScriptUrl"] = "true";
mainListsNode.Update();

you need only specify js function and mark that this external link, and that's it. I mistakenly thought that correlation exists between SPNavigationNode properties and dataItem.

2
  • Dear Kai, that worked. I had a feeling it was the Properties that need to be set but couldn't find any site explaining what properties there are.
    – David
    Jan 19, 2012 at 7:18
  • Please, refer to my update, I found that some lines are redundant. Jan 19, 2012 at 7:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.