Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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 achive 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;
    }
}
share|improve this question
add comment

1 Answer 1

up vote 4 down vote accepted

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.

share|improve this answer
    
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 '12 at 7:18
    
Please, refer to my update, I found that some lines are redundant. –  Kai Jan 19 '12 at 7:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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