3

I have implemented the jQuery UI autocomplete functionality on a input field using JSLink.

It works like a charm when I test it using Internet Explorer 9, 10, 11 and Chrome.

Some users are however getting a JavaScript error which seems to break the autocomplete functionality, while others who gets it are not bothered at all.

Uncaught TypeError: Cannot read property 'toString' of undefined

Looking at the stacktrace if might have something to do with SP.List.getItemById, but I cannot see how I can do anything different. Does anyone have any ideas?

Here is the most important bits of the code:

// Create function for customizing Field rendering
CourseAutocompleteField.customizeFieldRendering = function () {
var fieldJsLinkOverride = {};
fieldJsLinkOverride.Templates = {};
fieldJsLinkOverride.Templates.Fields = {
    // Hook internal field name up with the rendering method
    "envi_course": {
        "NewForm": CourseAutocompleteField.renderField,
        "EditForm": CourseAutocompleteField.renderField
    },
};

// Register rendering template
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(fieldJsLinkOverride);
};
// Rendering functions for Course Autocomplete field
CourseAutocompleteField.renderField = function (ctx)
{

// Insert jQuery library
var jq = document.createElement('script');
jq.src = window.location.protocol + "//" + window.location.host +   "/_layouts/15/w.e.e/libraries/jquery-ui.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);

// Insert autocomplete stylesheet
var css = document.createElement('link');
css.rel = 'stylesheet';
css.href = window.location.protocol + "//" + window.location.host + "/_layouts/15/w.e.e/css/autocomplete.css";
document.getElementsByTagName('head')[0].appendChild(css);

// Make sure sp.js is loaded
SP.SOD.executeFunc('sp.js', 'SP.ClientContext',     CourseAutocompleteField.getCourseValues);

// return input field
var result = SPFieldText_Edit(ctx); // render text field using built-in CSR function
var $f = $(result);
return $f.html();
};

Using SP.SOD.executeFunc I make sure that sp.js is loaded and using the method below I get the data needed for autocomplete.

CourseAutocompleteField.getCourseValues = function () {
try {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var predefinedCoursesList = web.get_lists().getByTitle('Prædefinerede forløb');

    var query = new SP.CamlQuery();
    var xml = [];
    xml.push('<View>');
    xml.push('<Query>');
    xml.push('<Where>');
    xml.push('<IsNotNull>');
    xml.push('<FieldRef Name="envi_course" />');
    xml.push('</IsNotNull>');
    xml.push('</Where>');
    xml.push('<OrderBy>');
    xml.push('<FieldRef Name="envi_course" Ascending="False" />');
    xml.push('</OrderBy>');
    xml.push('</Query>');
    xml.push('<ViewFields>');
    xml.push('<FieldRef Name="envi_course" />');
    xml.push('<FieldRef Name="envi_organizer" />');
    xml.push('<FieldRef Name="envi_desc" />');
    xml.push('</ViewFields>');
    xml.push('</View>');

    query.set_viewXml(xml.join(''));

    this.courseItems = predefinedCoursesList.getItems(query);

    context.load(this.courseItems);

    context.executeQueryAsync(
        Function.createDelegate(this, CourseAutocompleteField.renderCourseField),
        Function.createDelegate(this, CourseAutocompleteField.errorGetCourseValues)
    );
}
catch (e) {
    console.log(e.message);
}
};

And finally we render it.

CourseAutocompleteField.renderCourseField = function () {
var field = $('input[id^="envi_course"]');
var listEnumerator = this.courseItems.getEnumerator();
while (listEnumerator.moveNext()) {
    var item = listEnumerator.get_current();
    CourseAutocompleteField.courses.push({
        label: item.get_item('envi_course'),
        value: item.get_item('envi_course'),
        organizer: item.get_item('envi_organizer'),
        description: item.get_item('envi_desc')
    });
}

field.autocomplete({
    minLength: 0,
    source: CourseAutocompleteField.courses,
    focus: function (event, ui) {
        field.val(ui.item.value);
        return false;
    },
    select: function (event, ui) {
        field.val(ui.item.value);
        $('input[id^="envi_organizer"]').val(ui.item.organizer);
        $('textarea[id^="envi_desc"]').val(ui.item.description);
        return false;
    },
    response: function (event, ui) {
        return false;
    }
}).autocomplete("instance")._renderItem = function (ul, item) {
    return $("<li>").append("<a>" + item.value + "</a>").appendTo(ul);
};
};

And it's initiated by calling "CourseAutocompleteField.customizeFieldRendering();"

1 Answer 1

0

I notice that you didn't include IE8 in your list of browsers that you tested against.

SharePoint 2010 masterpages by default force Internet Explorer 9 through 11 to emulate IE8. Even without the masterpage explicitly asking for IE8 mode, users (or IT departments) can configure Internet Explorer to run in "compatibility mode," when viewing certain URLs, which again emulates IE8.

Any JavaScript functionality that fails in IE8 will also fail in IE9, 10, and 11 if they are running in compatibility mode.

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.