Sunday, December 7, 2014

How i've won MS : Sort Content Search Web Part via JS, and all other functions that should be from the QS

my scenario was ordering the search results, and i really wanted to make it with CSWP, and my CTO wanted the odering via QS, so he found me this:

that was great until it needed to be embedded with some OOTB refiners, my little script overran sharepoint's OOTB behavior since they use the QS as well, and so started the fight to find how to do it OOTB.

in the beginning i found zelion posts about "Srch.U.fillKeywordQuery", which is great but i couldn't find that JSON object.

i then looked into the objects on the page and found that my object was  "Srch.QueryState", but no way was found to update it and send the request.

but i didn't gave up. all those posts with all those ways to refresh the "Search Content WP" made me feel that there is a way, a simple way that does not involve all kind of "ClientContext" objects and such. i needed to debug MS functions:

var originalFillKeywordQuery = Srch.U.fillKeywordQuery;
Srch.U.fillKeywordQuery = function (query, dp) {
    originalFillKeywordQuery(query, dp);

I then got the callstack:

which was actually all this:
Srch.U.appendArray (search.clientcontrols.js:1)
Srch.DataProvider.$5O_3 (search.clientcontrols.js:1)
(anonymous function) (ScriptResource.…yYEj39UB3gJ…:5)
EnsureScript (init.js:1)
Srch.DataProvider.issueQuery (search.clientcontrols.js:1)
Srch.DataProvider.displayControl_QueryReady (search.clientcontrols.js:1)
(anonymous function) (ScriptResource.…yYEj39UB3gJ…:5)
(anonymous function) (ScriptResource.…yYEj39UB3gJ…:5)
Srch.DisplayControl.raiseQueryReadyEvent (search.clientcontrols.js:1)
Srch.Refinement.addRefinementFiltersWithOp (search.clientcontrols.js:1)
Srch.Refinement.addRefinementFilters (search.clientcontrols.js:1)
Srch.Refinement.addRefinementFiltersJSON (search.clientcontrols.js:1)
onclick (KnittingPortal:1)

my eyes caught Srch.DataProvider.issueQuery.
after all my search i already knew that my CS is a Srch.DataProvider object, just get the "DataProvider" element wrapping it:
var dp = $getClientControl($('#DataProvider')[0]);

but the CS DataProvider object does not come with all the "raiseXXX" functions like the refiners control, but he must have had some function to update itself, so i checked if issueQuery is his own function, plus i found that it does not take parameters, i felt it.

i needed to change the QueryState, it was in the Srch.DataProvider object under "$2_3", and then i called issueQuery and i felt redemption!

with this we can make any refinements and/or sorters or any other functionality for out search WPs without relying on OOTB WPs at all with simple JS.

here my full code
MyNS.SorterObjects = [//text is the ddl text, o is the actual value to be set in the QueryState.o object
{ Text: "ALL", o: "" },
{ Text: "Phase Asc", o: '[{"d":1,"p":"RefinableString10"}]' },
{ Text: "Phase Desc", o: '[{"d":0,"p":"RefinableString10"}]' },
{ Text: "Created Asc", o: '[{"d":1,"p":"Created"}]' },
{ Text: "Created Desc", o: '[{"d":0,"p":"Created"}]' },
{ Text: "Modified Asc", o: '[{"d":1,"p":"LastModifiedTime"}]' },
{ Text: "Modified Desc", o: '[{"d":0,"p":"LastModifiedTime"}]' }
];var ddl = $(".sorter .sorterWorker select");
for (i = 0; i < MyNS.SorterObjects.length; i++) {
    var o = MyNS.SorterObjects[i];
    ddl.append($("<option></option>").attr("data-o", o.o).text(o.Text));
ddl.on('change', function (e) {
    var optionSelected = $("option:selected", this);
    var o = optionSelected.attr("data-o");
    var dp = $getClientControl($('#DataProvider')[0]);
    dp.$2_3.o = jQuery.parseJSON(o);    dp.issueQuery();


  1. Great Success ,Bro :)

  2. Excellent work hombre. This saved me much time, and brought functionality to the people. You are greater than the offspring of Gandhi and Mother Theresa. Your tagline is "Developing with the help of God", but I think God is developing with the help of you. I believe you could code circles around Rabi Nachman in your sleep, don't sell yourself short. Praise be.

  3. na nach power babe! every thing is possible