How can I implement a "Related questions" feature like the one on Stack Overflow? - asp.net

I want to implement a feature similar to the "Related Questions" list shown when asking a question on Stack Overflow. I like how the related questions populated when the Title is filled in.
I am using ASP.NET and jQuery. How might I implement something like this? Can anyone point to examples?
I looked at the source of the ask question page and I don't see any onblur or focus calls.

As a matter of fact there is a call. This bit of code is responsible for the GET request which is sent to the server ob 'blur' of the #title input element (it's in the source of the page, close to the top):
$().ready(function() {
$("#title").blur(function() { QuestionSuggestions(); });
});
function QuestionSuggestions() {
var s = $("#title").val();
if (s.length > 2) {
document.title = s + " - Stack Overflow";
$("#question-suggestions").load("/search/titles?like="
+ escape(s));
}
}

I was thinking of implementing something similar, although this may not be an answer to your question, here is what I was planning to do:
When a question is saved parse it and create a topic word to uniqueid (of the post) mapping and save in database indexed by word.
When a new question is typed and the focus go out of the title, make an AJAX call with all the relevant words from the database and match all the similar ids that is common (so that at least two words have the same id)
Populate with div that is dynamically made visible.
I am interested to know if anyone has more insight on this...

Related

Display Text for QnAMaker follow-on prompts

I'm attempting to use follow-on prompts within QnAMaker but am confused about the purpose of the field labelled "Display text" in the "Follow-up prompt" creation dialogue. https://learn.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/multiturn-conversation describes this field as "The custom text to display in the follow-up prompt.". To me, that suggests that it's just a label for the follow-up prompt which is typically rendered as a button. I therefore assumed that the text had no purpose other than as a label and that the button would be directly linked to the chosen question / answer pair. However, from experimenting with a QnAMaker knowledge base, it seems that the "Display text" is actually passed to the QnAMaker service and this text is used to search for the answer. This means that the "Display text" value has to be chosen for the purpose of both labelling the button and successfully finding the follow-on answer.
This means I can't use short follow-on prompts such as "How do I pay for it?" or "How do I join it?" where the main Q/A pair relates to one of various services as these strings won't reliably return the intended answer. Rather, the prompts will have to be the more verbose "How do I pay for service A" and "How do I join service A".
Have I understood this correctly? I don't think the documentation makes this at all clear...
Multi-turn QnA Maker conversations are still in preview and there is currently no SDK to help you build a bot that knows how to interact with the follow-up prompt API. You are ultimately in control, and so you get to have your bot treat the display text however it wants. All the "display text" is is a value that you've inserted into an answer in your knowledge base so that it gets returned along with the answer after a call to generateAnswer.
It can be very helpful to have your display text match the text of the question you're linking to because then the prompt's display text can be used to access the correct follow-up QnA pair, so long as the context is included in the API call. That's what happens in this sample. It sounds like you want to get it to work without having the prompt's display text match the text of the follow-up question. That can get tricky, but here's something you can do.
Remember that you specify more than just display text when you make follow-up prompts. You also link to a specific QnA pair. This allows the API to return that QnA ID to you along with the display text. You haven't mentioned which channel your bot is targeting, but if you're using a channel that supports postBack or messageBack actions then you can pass the QnA ID to your bot invisibly and then your bot can use that to access the answer. If you go this route, you may not even need to worry about dialogs or state. You also haven't mentioned what language you're coding your bot in, but here's an example of how this might be implemented in Node.js:
async testQnAMaker(turnContext) {
var qna = new QnAMaker({
knowledgeBaseId: '<GUID>',
endpointKey: '<GUID>',
host: 'https://<APPNAME>.azurewebsites.net/qnamaker'
});
var value = turnContext.activity.value;
var qnaId = value && value.qnaId;
// qnaId will be undefined if value is empty
var results = await qna.getAnswers(turnContext, { qnaId });
var firstResult = results[0];
if (firstResult) {
var answer = firstResult.answer;
var resultContext = firstResult.context;
var prompts = resultContext && resultContext.prompts;
if (prompts && prompts.length) {
var card = CardFactory.heroCard(
answer,
[],
prompts.map(prompt => ({
type: 'messageBack',
title: prompt.displayText,
displayText: prompt.displayText,
text: prompt.displayText,
value: { qnaId: prompt.qnaId }
}))
);
answer = MessageFactory.attachment(card);
}
await turnContext.sendActivity(answer);
} else {
await turnContext.sendActivity("I can't answer that");
}
}
Note that this does have some limitations. Because it works by retreiving the QnA ID from the activity's value property, it may not be able to find the correct QnA pair if the user types in the text of the button manually instead of clicking the button.
If you want to make the display text work on its own without relying on the QnA ID, you could save your own mappings so that your bot knows which display text values correspond to each QnA ID in each context. However, you might also consider just adding the display text as an alternative phrasing of the question in the QnA pair. So "How do I pay for service A" and "How do I pay for service B" could both have "How do I pay for it" as a form of the question. Because you'll now have duplicated phrasings in multiple QnA pairs, you'll need to pass the context in your calls to generateAnswer for this to work.
See this answer for more info about multi-turn conversations.

ServiceStack proper way to access routes and avoid markup

I think this question is more about best practices regarding web services and not necessarily limited to ServiceStack only. From what I've read here and on the SS wiki, the 'recommended' way to implement parent-child entities is to break them down via routes.
For example:
/Users/{UserID}
/Users/{UserID}/Entities
Where User is the logged on user, and entities are his/her items. I'm implementing jqueryui autocomplete and here is where I'm suspecting I'm not doing the right thing.
In the script the path needs the Userid, so I have to manually render it in the browser so that it reads:
type: "GET",
url: "svc/users/**8**/entities",
data: { "SearchTerm": request.term, "Format": 'json' },
This smells wrong to me. I have the UserID from the session and I can get it that way. So I wonder if there a better way to access these objects without having to render data directly into markup?
Am I doing this wrong?
On a side note: I know I could place this data in a hidden field and access it via script etc, I am just curious if there is a better/recommended way to do this via sessions while keeping the routes as is.
Generally this is done with another endpoint, Facebook for instance, uses /my/, but you could do what ever you want.
The reason being, it's very likely you will be returning different information for a user about themselves than you share about that user with someone else.
Let's pretend /user/{UserId}/books returns a user's favorite books. If I want to know what someone's favorite books are, I might be interested in the title, and a brief description, but if I want to see (and possibly manage) my list of favorite books then I might want more information, like the day I added the favorite book, or friends of mine that also like the book.
so /user/{UserId}/books returns:
{
"books":[
{ "title":"Hary Potter", "desc":"A boy who is magic..." }
]
}
however /my/books returns:
{
"books":[
{
"title":"Harry Potter",
"desc":"A boy who is magic...",
"friensWhoLikeBook":[
{ "id":1234, "name":"Bob" }
],
"personalCommentsAboutBookNotToBeShared":"This book changed my life..."
}
]
}

Broad cast message to specific page using signalr

suppose i have forum where people post their question and another people post the answer. say for example person A post a question "What is signalr ?" and stand at that page. other person also open that page for answering. if other person post any answer then i want that that answer will be shown in that page open by other users. suppose five user open that page and one of them answer then five user will see that answer.
normally when we like to broadcast any message to all then we use syntax like at server end
Clients.All.broadcastMessage(name, message);
so according to my above situation what kind of syntax i need to use?
here are few guide i found for broad cast message type and those are follows
// Call send on everyone
Clients.All.send(message);
// Call send on everyone except the caller
Clients.Others.send(message);
// Call send on everyone except the specified connection ids
Clients.AllExcept(Context.ConnectionId).send(message);
// Call send on the caller
Clients.Caller.send(message);
// Call send on everyone in group "foo"
Clients.Group("foo").send(message);
// Call send on everyone else but the caller in group "foo"
Clients.OthersInGroup("foo").send(message);
// Call send on everyone in "foo" excluding the specified connection ids
Clients.Group("foo", Context.ConnectionId).send(message);
// Call send on to a specific connection
Clients.Client(Context.ConnectionId).send(message);
which one i need to use ? please explain & thanks.
You could have a div on the page that has an id of the question. So you would have something like:
<div id="theAskedQuestionId"><!-- the answer will be inserted here--></div>
so for example:
<div id="12345"><!-- the answer will be inserted here--></div>
And then you can use jquery to inject the answer into the div. An example of this is:
var messagePublisher = $.connection.yourHubName;
messagePublisher.client.broadcastMessage = function(divId, message){
$(divId).html(message); //note: divId will be something like #12345
};
This will allow you to only show the message to the users that are looking at the specific question instead of broadcasting the message to users looking at any question. I think this is what you were asking for help on.

Framebuster with exceptions

I have a question about writing a frame-buster-buster. I have already read Frame Buster Buster ... buster code needed but I need an extra tweak.
My content from my blog at [http://my_domain.c0m/blog] is being displayed at another site showing three "views". One view is a feed and doesn't particulary bother me. The other two bother me and I wish to break both. I also want to permit exceptions of domains with permission to frame.
In one view, it appears the the content from the top of my html of the top of my blog is first copied to create a "snapshot" [http://the_other_domain.c0m/copy_of_blog] then that copy is framed in [http://the_other_domain.c0m/ ]. So, in this case, the 'child' copy are both hosted at [http://the_other_domain.c0m/] . Google translate does a similar thing-- but I find this ok. So, I would like to break this frame while also permitting exceptions for google and also for people who have made a copy to their pcs and would like to view in a utility that might frame.
In the other view, it appears the content from my site is framed. So in this case [http://my_domain.c0m/blog_post] is framed by [http://the_other_domain.c0m/]. I would like to bust out of this frame. However, my difficulty is that I can't figure out how to do so while keeping the exceptions for google translate or individual pc users frames at home.
My solution so far (I am not particularly familiar with javascript. So, please don't laugh too hard at the redundancy and lack of knowledge):
I was able to bust the first frame using:
<SCRIPT type="text/javascript" >
var topWindow = String(top.location)
var topWord=topWindow.split("/")
var selfWindow = String(self.location)
var selfWord=topWindow.split("/")
var correctLocation ="http://my_domain.c0m/blog"
var correctWord2="my_domain.c0m"
var http="http:"
if( ( (topWord[2] != correctWord2) || (selfWord[2] != correctWord2) )
&& (topWord[2] != 'translate.googleusercontent.com' ) && (topWord[0] == http ) ){
document.write("message expressing my opinion about the asshattery going in here.]" )
setTimeout("redirect_after_pause()",8000)
}else{
//document.write("<p><font color='purple'>Hi there! Javascript is working.</font> </p> " )
}
function redirect_after_pause() {
var correctLocation ="http://my_domain.c0m/blog"
top.location=correctLocation
}
I know this is inefficient. But it works and achieves my goal of making an exception for a) translations at googlecontent which my readers in france requested and b) cases where a user is framing in a utility that downloads to their pc (which I think has uri's beginning with "FILE:".
Now the difficulty: This does not work for the view where content hosted at my domain is framed at the other domain. I believe I have tracked the problem down to var topWindow = String(top.location) not being permitted in my child window. In principle, this would work:
<script type="text/javascript">
if(top != self) top.location.replace(location);
However, I think it screws up the use of google translate which uses a top frame that holds their translation of my content also hosted at [http://translate.google.com]. I suspect it similarly screws up readers that might display a local copy on someones pc if that copy is displayed in a frame.
If someone can guide me toward a solution I can implement to break both frames while permitting my exception
BTW: It does appear that the site in question is using a framebuster. I poked around and found this inside their /static/common.js?1345250291 code:
enable_iframe_buster_buster:function(){var a=this,b=0;window.onbeforeunload=function(){b++};clearInterval(this.locks.iframe_buster_buster);this.locks.iframe_buster_buster=setInterval(function(){0<b&&(b-=2,a.flags.iframe_story_locations_fetched&&!a.flags.iframe_view_not_busting&&_.contains(["page","story"],a.story_view)&&NEWSBLUR.reader.active_feed&&($(".NB-feed-frame").attr("src",""),window.top.location="/reader/buster",$(".task_view_feed").click()))},1)},disable_iframe_buster_buster:function(){clearInterval(this.locks.iframe_buster_buster)}
That's deep inside some particulary dense javascript. Whatever it does it doesn't seem to affect my ability to bust the frame for the case where my content is copied and hosted at [http://the_other_domain.c0m/]. I haven't yet fully explored whether it busts simple framebusters because earlier I only recently recognized that " var topWindow = String(top.location) " was forbidden in the child frame with a different domain from the parent frame.
Whether or not the frame-buster is present, I'd like help with solutions here. I know that if one site is now framing my content in this way it is only a matter of time before the obnoxious technique catches on and I would like to code in solutions that bust both methods gracefully while providing myself with exceptions. Thanks in advance.

Read from values from hidden field values in Jquery?

Last two nights I am struggle with below code. The problem is I need to remember expanded (or) collapsed toggles sections and on page reload I have show them as is expanded (or) collapsed.
$(function() {
$('tr.subCategory')
.css("cursor", "pointer")
.attr("title", "Click to expand/collapse")
.click(function() {
$(this).siblings('.RegText').toggle();
});
$('tr[#class^=RegText]').hide().children('td');
})
I found small solution in another forum like this. Storing ".subCategory" id values in hidden field in commas-seperated values.
In Asp.net page:
<input id="myVisibleRows" type="hidden" value="<% response.write(myVisibleRowsSavedValue) %" />
In .js:
var idsStr = $(#myVisibleRows).val();
Now My question is: How to store multiple values (.subCategory id) in hidden field when I click on toggle?. also How to parse them back and iterate them get ids and show toggles?. I am very very new to jQuery. Please some one help me out from this.
Passing this kind of values in a form isn't probably the best thing to do it. I'd suggest using cookies to store expanded sections id's or something similar. It's much easier to implement and you are not passing unimportant form data between requests. If you want to store multple values you can serialize them (easiest thing: use join function in JS) before you store them and deserialize (split) after reading it from a cookie.

Resources