7
\$\begingroup\$

I've recently assembled some jQuery that allows a user to build out a bulleted list in MS Word with hyperlinks and turn that into a HTML unordered list. Ideas for uses are website menu systems where the user may not have a clue about HTML. You can also extend this with jQuery UI plugins for effects. Looking for edge cases.

/*
    The following will read in a bullet list from in a MS Word XML file and turn it into a 
    unordered list with hyperlinks. Perhaps to use as a menu.
*/
$.ajax({
    type: "GET",
    async: false,
    url: "Menu.xml",
    dataType: "xml",
    success:function(results){
        var currentDepth = 0;
        $("#menu").append('<ul class="menuLvl'+currentDepth+'"></ul>');
        $(results).find("[nodeName=w:p]").each(function(){
            if($(this).find("[nodeName=w:pStyle]").attr('w:val') == 'ListParagraph'){
                var liValue = $(this).find("[nodeName=w:t]").text();
                var hyper = $(this).find("[nodeName=w:hyperlink]").attr('r:id');
                var placeAtDepth = parseInt($(this).find("[nodeName=w:ilvl]").attr('w:val'), 10);

                if(placeAtDepth > currentDepth){
                    $(".menuLvl"+ currentDepth).append('<ul class="menuLvl'+ placeAtDepth +'">');
                }   

                currentDepth = placeAtDepth;

                //Determine if we have an hyperlink
                if(hyper != null){
                    var link = $(results).find('Relationship[Id='+hyper+']').attr('Target');
                    liValue = '<a href="'+ link +'">'+ liValue +'</a>';
                }

                $(".menuLvl"+currentDepth).last().append('<li>'+ liValue +'</li>');
            }
        });
    }
});
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Looks fine (maybe some stricter formatting could help readibility, but not an issue), so I'll suggest completely optional improvements that might help spotting important improvements.

As a general principle, try to be ready for bogus values in your input so you can avoid generating nonsense. Being more robust will also make reusing your code for somewhat different tasks easier.

$.ajax({
/// [...]
    success:function(results){
/// [...]
        $(results).find("[nodeName=w:p]").each(function(){
            if($(this).find("[nodeName=w:pStyle]").attr('w:val') == 'ListParagraph'){
                var liValue = $(this).find("[nodeName=w:t]").text();
/// -^ What if the input has an empty value here? Skip? 

                var hyper = $(this).find("[nodeName=w:hyperlink]").attr('r:id');
                var placeAtDepth = parseInt($(this).find("[nodeName=w:ilvl]").attr('w:val'), 10);
/// -^ parseInt can return a NaN, maybe you want to bail out in that case?
///    Should also handle some bogus results for .find.

                if(placeAtDepth > currentDepth){
                    $(".menuLvl"+ currentDepth).append('<ul class="menuLvl'+ placeAtDepth +'">');
                }

                currentDepth = placeAtDepth;

                //Determine if we have an hyperlink
                if(hyper != null){
                    var link = $(results).find('Relationship[Id='+hyper+']').attr('Target');
/// -^ This can result in an invalid link for broken input. But what if
       the input is malicious (JS hrefs)? 

                    liValue = '<a href="'+ link +'">'+ liValue +'</a>';
\$\endgroup\$

Your Answer

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

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