Category Archives: DFFS Plugin

vLookup inline editing examples

There is no built in support for inline editing in the vLookup script, but you can add custom code to add support. Here is a few examples.

Add this to your Custom CSS

.vLookupDispWrap{
     padding-left:1.1em;
     cursor:pointer;
     width:100%;
     box-sizing:border-box;
     white-space: normal;
 }
 .vLookupDispWrap:hover:before{
     content:"\270e";
     float:left;
     margin-left:-1.1em;
 }
 .vLookupEditWrap{
     display:none;
     width:100%;
     box-sizing:border-box;
 }

Add these shared functions to your Custom JS

 // Field type choice - dropdown
function edit_inline_dropdown(val, id, listGuid, fin, choices) {
    var dVal = val, b = [];
    if (dVal === "") {
        dVal = " ";
    }
    b.push("<div style='white-space:nowrap;'>");
    b.push("<div class='vLookupDispWrap' onclick='toggleEditField(this);'>");
    b.push("<span class='vLookupCurrVal'>" + dVal + " </span>");
    b.push("</div>");
    b.push("<div class='vLookupEditWrap'>");
    b.push("<select>");
    jQuery.each(choices, function (i, v) {
        b.push("<option value='" + v + "'");
        if (val === v) {
            b.push(" selected='selected'");
        }
        b.push(">" + v + "</option>");
    });
    b.push("</select>");
    b.push("<span title='Save' style='cursor:pointer;margin:3px;color:green;font-weight:bold;' onclick='saveChangesInput(this,\"" + fin + "\",\"" + id + "\",\"" + listGuid + "\")'>✔</span>");
    b.push("</div>");
    b.push("</div>");
    return b.join("");
}

// Field type choice - multichoice
function edit_inline_multichoice(val, id, listGuid, fin, choices) {
    var dVal = val, arr = val.split(/<br\s*\/?>/i), b = [];
    if (dVal === "") {
        dVal = " ";
    }
    b.push("<div style='white-space:nowrap;'>");
    b.push("<div class='vLookupDispWrap' onclick='toggleEditField(this);'>");
    b.push("<span class='vLookupCurrVal'>" + dVal + " </span>");
    b.push("</div>");
    b.push("<div class='vLookupEditWrap'>");
    jQuery.each(choices, function (i, v) {
        b.push("<input id='inline_" + fin + "_" + i + "' type='checkbox' value='" + v + "'");
        if (jQuery.inArray(v, arr) > -1) {
            b.push(" checked='checked'");
        }
        b.push("/><label for='inline_" + fin + "_" + i + "'>" + v + "</label><br>");
    });
    b.push("<span title='Save' style='cursor:pointer;margin:3px;color:green;font-weight:bold;' onclick='saveChangesMultichoice(this,\"" + fin + "\",\"" + id + "\",\"" + listGuid + "\")'>✔</span>");
    b.push("</div>");
    b.push("</div>");
    return b.join("");
}

// Field type multiline plain text
function edit_inline_textarea(val, id, listGuid, fin) {
    var dVal = val, b = [];
    if (dVal === "") {
        dVal = " ";
    }
    val = val.split(/<br\s*\/?>/i).join("\n");
    b.push("<div style='white-space:nowrap;'>");
    b.push("<div class='vLookupDispWrap' onclick='toggleEditField(this);'>");
    b.push("<span class='vLookupCurrVal'>" + dVal + " </span>");
    b.push("</div>");
    b.push("<div class='vLookupEditWrap'>");
    b.push("<textarea style='height:75px;width:100%;box-sizing:border-box;'>" + val + "</textarea>");
    b.push("<span title='Save' style='cursor:pointer;margin:3px;color:green;font-weight:bold;' onclick='saveChangesInput(this,\"" + fin + "\",\"" + id + "\",\"" + listGuid + "\")'>✔</span>");
    b.push("</div>");
    b.push("</div>");
    return b.join("");
}

// Field type single line of text
function edit_inline_text(val, id, listGuid, fin) {
    var dVal = val, b = [];
    if (dVal === "") {
        dVal = " ";
    }
    b.push("<div style='white-space:nowrap;'>");
    b.push("<div class='vLookupDispWrap' onclick='toggleEditField(this);'>");
    b.push("<span class='vLookupCurrVal'>" + dVal + " </span>");
    b.push("</div>");
    b.push("<div class='vLookupEditWrap'>");
    b.push("<input type='text' value='" + val + "'>");
    b.push("<span title='Save' style='cursor:pointer;margin:3px;color:green;font-weight:bold;' onclick='saveChangesInput(this,\"" + fin + "\",\"" + id + "\",\"" + listGuid + "\")'>✔</span>");
    b.push("</div>");
    b.push("</div>");
    return b.join("");
}

// Save function for input, select and textarea
function saveChangesInput(elm, fin, id, listGuid) {
    var val = jQuery.trim(jQuery(elm).prev().val());
    saveInline_vLookupChanges(elm, val, fin, id, listGuid);
}

// Save function for multichoice
function saveChangesMultichoice(elm, fin, id, listGuid) {
    var arr = [], val;
    jQuery(elm).parent().find("input:checkbox:checked").each(function (i, o) {
        arr.push(jQuery(o).val());
    });
    val = arr.join(";#");
    saveInline_vLookupChanges(elm, val, fin, id, listGuid);
}

function toggleEditField(elm) {
    jQuery(elm).hide().next().show();
}

function saveInline_vLookupChanges(elm, val, fin, id, listGuid) {
    var dataObj = {}, res, eId;
    dataObj[fin] = val;
    res = spjs.utility.updateItem({ "listName": listGuid, "id": id, "data": dataObj });
    if (res.success) {
        // Choice columns
        val = val.split(";#").join("<br>");
        val = val.split("\n").join("<br>");
        jQuery(elm).parent().hide().prev().html(val + " ").show();
    } else {
        eId = new Date().valueOf();
        jQuery(elm).hide().after("<span id='" + eId + "' title='" + res.errorText + "' style='cursor:default;margin:3px;color:red;font-weight:bold;'>!</span>");
        setTimeout(function () {
            var prev = jQuery("#" + eId).prev();
            jQuery(prev).show().next().remove();
        }, 5000);
    }
} 

Text field example

Add this to your text field in the vlookup ViewFields Special configuration:

{"function":"edit_inline_title"}

Then add this to your Custom JS:

function edit_inline_title(val, item){
    var listGuid = "{ccbbf922-f0af-481b-b2c0-b12ea24d224e}", fin = "Title", id = item.get_item("ID");
    return edit_inline_text(val, id, listGuid, fin);
} 

Change the variable listGuid and fin to match the vLookup child list and the field name you are editing.

Multiline plain text field

Add this to your multiline plain text field in the vLookup ViewFields Special configuration:

{"function":"edit_inline_description"}

Then add this to your Custom JS:

function edit_inline_description(val, item){
    var listGuid = "{ccbbf922-f0af-481b-b2c0-b12ea24d224e}", fin = "Description", id = item.get_item("ID");
    return edit_inline_textarea(val, id, listGuid, fin);
} 

Change the variable listGuid and fin to match the vLookup child list and the field name you are editing.

Dropdown choice field

Add this to your choice field in the vlookup ViewFields Special configuration:

{"function":"edit_inline_status"}

Then add this to your Custom JS:

 function edit_inline_status(val, item) {
    var listGuid = "{ccbbf922-f0af-481b-b2c0-b12ea24d224e}", fin = "Status", choices = ["Not started", "In progress", "Completed"], id = item.get_item("ID");
    return edit_inline_dropdown(val, id, listGuid, fin, choices);
}

Change the variable listGuid and fin to match the vLookup child list and the field name you are editing and change the choices array to match your fields choices.

Multichoice field

Add this to your choice field in the vlookup ViewFields Special configuration:

{"function":"edit_inline_color"}

Than add this to your Custom JS:

function edit_inline_color(val, item) {
    var listGuid = "{ccbbf922-f0af-481b-b2c0-b12ea24d224e}", fin = "Color", choices = ["Red", "Blue", "Green"], id = item.get_item("ID");
    return edit_inline_multichoice(val, id, listGuid, fin, choices);
}

Change the variable listGuid and fin to match the vLookup child list and the field name you are editing.

People picker field

Thanks to Brett Anderson for writing up most of this example.

Add this to your people picker field in the vlookup ViewFields Special configuration:

{"function":"edit_inline_AssignedTo"}

Than add this to your Custom JS:

function edit_inline_AssignedTo(val, item){
     var listGuid = "{ccbbf922-f0af-481b-b2c0-b12ea24d224e}", fin = "AssignedTo", id = item.get_item("ID");
     return edit_inline_pp(val, id, listGuid, fin);
 }
 
function edit_inline_pp(val, id, listGuid, fin) {
    var ppid = "pp" + id, dVal = val, b = [];
    if (dVal === "") {
        dVal = "Click to add name";
    }
    b.push("<div style='white-space:nowrap;' >");
    b.push("<div class='vLookupDispWrap' onclick='toggleEditField(this);' >");
    b.push("<span class='vLookupCurrVal' > " + dVal + " </span>");
    b.push("</div>");
    b.push("<div class='vLookupEditWrap' >");
    b.push("<div id='" + ppid + "' onkeydown='event.stopPropagation()' style='height:22px' >");
    function showPP() {
        var schema = {};
        schema.PrincipalAccountType = 'User,DL,SecGroup,SPGroup';
        schema.SearchPrincipalSource = 15;
        schema.ResolvePrincipalSource = 15;
        schema.AllowMultipleValues = false;
        schema.MaximumEntitySuggestions = 50;
        schema.Width = '200px';
        schema.Height = '50px';
        this.SPClientPeoplePicker_InitStandaloneControlWrapper(ppid, null, schema);
    }
    setTimeout(function () {
        showPP();
    }, 250);
    b.push("</div>");
    b.push("<span title='Save' style='cursor:pointer;margin:3px;color:green;font-weight:bold;' onclick='saveChangesPP(this,\"" + fin + "\",\"" + id + "\",\"" + listGuid + "\")'>✔</span>");
    b.push("</div>");
    b.push("</div>");
    return b.join("");
}

function saveChangesPP(elm, fin, id, listGuid) {
    var ppid = "pp" + id, idArr = [], pp = SPClientPeoplePicker.SPClientPeoplePickerDict[ppid + "_TopSpan"], users = pp.GetAllUserInfo(), dispNameArr = [], dataObj = {}, res, eId;
    // Get current PP values
    jQuery.each(users, function (i, o) {
        dispNameArr.push(o.DisplayText);
        idArr.push(spjs.utility.userInfo(o.Key).ID);
    });
    jQuery(elm).parent().hide().prev().html(dispNameArr.join(", ") + " ").show();
    dataObj[fin] = idArr.join(";#;#");
    res = spjs.utility.updateItem({ "listName": listGuid, "id": id, "data": dataObj });
    if (!res.success) {
        eId = new Date().valueOf();
        jQuery(elm).hide().after("<span id='" + eId + "' title='" + res.errorText + "' style='cursor:default;margin:3px;color:red;font-weight:bold;'>!</span>");
        setTimeout(function () {
            var prev = jQuery("#" + eId).prev();
            jQuery(prev).show().next().remove();
        }, 5000);
    }
} 

Change the variable listGuid and fin to match the vLookup child list and the field name you are editing.

Post any comments below, or create a new forum topic (if you do, please add the link to the post in the comments below so other users can find it).

Alexander

DFFS v4.4.3.0

After a loooong BETA period, and quite a few modification to DFFS and the plugins, I’m finally ready with a new production release.

There are a few nice additions like better backup / restore functionality with support for creating restore points, and new loader functionality that lets you load different DFFS versions side by side in the same site. This way you can do a gradual upgrade of DFFS  – one form at the time.

Please read the full change log to see all changes. You find the change log here: https://spjsblog.com/dffs/dffs-change-log/

Follow the download link here to get the new package.

Please note that the user manual hasn’t been updated yet, but I’ll do my best to update the manual within a few days.

Please post questions in the appropriate forum: https://spjsblog.com/forums/

Best regards,
Alexander

 

DFFS: New BETA version

I have made some changes to how jQuery loads using the “noConflict” loading option to ensure the correct version of jQuery is loaded, and that it’s not killed by other third party code loading jQuery again in the same page.

I need some feedback on how this performs before I can move it out of BETA. Please post any findings in the forum.

If it for some reason fails to load, please open the developer console by hitting F12 > Console and post any error messages you find there.

I have also added a new functionality to DFFS that lets “Linked rules and functions” (previously “And these rules or functions are true / false”) work “on change” to trigger the parent rule when the parent rule and all linked rules are validated to “true”. This setting must be turned on for each rule by checking the “Let linked rules trigger the parent rule on change” checkbox.

This functionality should make it easier to set up more complex rules.

You find the full changelog here.

Best regards,
Alexander

New version of the DFFS package

I have released a new DFFS package with a few new features and some bugfixes – you find the change log here.

The autocomplete plugin has been brushed up a bit, and the cascading dropdown plugin now supports an initial filter.

Both these plugins have gotten a new page with setup instructions – you find it in the products menu under DFFS plugins.

Post any comments in the forum.

Alexander

Cascading dropdowns – bugfix

SPJS-CascadingDropdowns.js v3.529 (October 10, 2016)

  • Fixed an issue where removing an option from one multiselect control did not clear the orphaned options in subsequent multiselect controls.

You find the changed file in the incremental releases folder by following the download link here. To update you must replace the file in the folder “/SPJS/DFFS/plugins”.

The complete change log for DFFS can be found here: https://spjsblog.com/dffs/dffs-change-log/

Dynamic forms for SharePoint v4.350 is out!

Production release is out!

I have finally finished the production release of DFFS v4.350 and vLookup v2.250 after a long BETA test period. I have not had all that much feedback on the latest BETA, and this can either mean there were no bugs, or that not so many have tested it.

I hope it is the first!

What is new?

The change log will be updated as soon as I can manage, but here is a few vital changes.

The installation process for all but the JSLink version for SP2013 has changed since the last production release. You find information in the updated installation manual. The user manual has also been updated with most of the new features, but I still have some parts left.

If you find a feature you cannot figure out, please look in the forum to see if the question has already been answered. If you cannot find it there, please post a new topic in the forum.

If you don’t have a user account, you find information in the top of each forum.

New license handling

All existing license codes (except the JSLink version) must be updated to a new format to support this new release.

This means you must send me an email to request an updated license.

Site collection scoped licenses

All site collection scoped licenses requires a “Challenge-Response” routine to generate the license key.

Please note that a site collection scoped license can only be used with one site collection. If you need more, you must upgrade your license. Read more here.

JSLink setup option

You find the “Challenge code” generation in the “Setup” page you created in the SPJS library.

CEWP setup option

You find a “License” tab in the backend or DFFS. The license added here will affect all DFFS instances in the current site.

Important information

I try to maintain backwards compatibility with older versions, but I cannot guarantee that all old configurations will upgrade without issues.

Back up you configuration before upgrading

Please BACK UP your configuration first by going to the Misc tab and Export the configuration to a text file.

This way you can restore your previous version if something did not perform as expected.

Plugins

All the plugins used with DFFS is included in this package

Download

Get the package here

Installation

See installation manual and user manual.

Best regards,
Alexander