knockout js bootstrap combobox custom binding - asp.net-mvc

I have a question regarding using bootstrap combobox plugin in conjunction with knockout (and mvc).
I have a situation where I am using out of box MVC html helpers like Dropdownlisfor, textboxfor, etc in my template. I am using Knockout to bind a collection of data to the template. The mvc html helpers create a 'select' control for the DropDownlistfor helper. I need this to be rendered before I want to call my bootstrap plugin on the control so that all the necessary validation attributes, etc are set up. I initially used afterrender and in that method, I found the 'select' control and called the plugin on it.
Our issue is we dont want to do this every time we have to use the bootstrap combobox control in a similar way somewhere else. So, I have been researching about Custom Bindings (which I should have done already in the first place) and had a question about how I can use custom bindings in my stuation.
I found this article where he created a custom binding for bootstrap typeahead control. I can make a similar one to that for combobox. But I can only call it after the control is rendered. So, is there a way for us to specify KO to only perform custom binding "afterrender" instead of right away. That way, the select control is rendered and I can then call the plugin in the custom binding over the select control.
Here is some more info.
I have a table which uses a template
<table>
<tbody data-bind='template: {name: "editorRowTemplate", foreach: rules, afterRender: function(data) {{$root.view.templateRendered(data) } }'> </tbody>
</table>
I have the template which is similar to this
<script id="editorRowTemplate" type="text/html">
<tr class="dataRow" data-bind="attr: { id: 'EditorRow' + $index() }">
<td>
<div class="editor-field">
#Html.KnockOutDropDownListFor(rule => ruleTemplate.ReserveWordId, new List<SelectListItem>(), null,
new { #class = "combobox", data_bind = "options: $root.ReserveWords, optionsText:'Name', optionsValue:'ReserveWordId', attr : {id: $index(), name: $index()}" }, ((int)this.Model.Prefix).ToString())
#Html.KnockOutValidationMessageFor(rule => ruleTemplate.ReserveWordId, "*", new { data_bind = "attr : { 'data-valmsg-for': $index()}" }, ((int)this.Model.Prefix).ToString())
</div>
</td>
</tr>
</script>
I have my own html helpers (KnockoutDropDownListFor, etc) which generate a select control with specified KO bindings.
Please suggest what would be a good way to go about it.
Let me know if you need more info.

I'm not sure I fully understand the question. However you do not need to worry about waiting for the MVC helpers to render because this will happen server side and the knockout stuff will happen client side.
You also can use $(document).ready(function() {...}); if you want to make sure the DOM has loaded before doing anything.

Related

Knockout JS and Razor - How to assign data to Razor variables?

I am working with a multi layer web application that uses various web technologies. It interacts with a WebAPI to get the data via Knockout JS.
I will try to narrow the scope of my question to this:
I have a span tag
<span id="title" data-bind="text: FullTitle"></span>
I would like to get the content of that span and assign it to a Razor variable.
I have tried:
#
{
var Test = <span id="title" data-bind="text: FullTitle"></span>
}
But this doesn't render the knockout code and it just assigns the full span code to that variable.
I just want to get the full title when knockout pulls it into the Test variable.
Note: the span works outside the razor block and displays the full title on the cshtml view.
Any ideas?
Thanks in advance.

Passing values from one partial view to another on the client side

is it possible send some parameter from one partialview to another .
i have 2 partial views . i wanna when i click on btn1(in partialone) , some parameters will be send to partial2 . of course without post back.
is it just possible with java script? is there any way?
for example i wanna send my td's values to second partial :
<tr>
<td class="tdPhone">2265176</td>
<td>Email :</td>
<td class="tdMobile" >fdg#gmail.com</td>
</tr>
<button class="btn btn-medium " data-type="submit">Next</button>
Partial views are finally rendered as divs in html page. So you will need to use client side javascript so that one div can talk to another. One of the cleanest technique will be to use triggers if you are using jquery. To send the data from one div on button click
$('body').trigger('div1-trigger-someBetterNameConventionWillHelp', [$('.tdPhone').innerHtml(),$('.tdMobile').innerHtml()]). and then another div where you wish to update it u can trap this trigger using
$('body').on('div1-trigger-someBetterNameConventionWillHelp', function(evt, data)
{
});
There is whole lot of caveat with this solution like you should try to identify the data with ids and not by classes and all, but just presenting the solution based on the question you asked.

knockout validation with typeahead combobox plugin

I am trying to use Knockout Validation in combination with Bootstrap Combobox Plugin.
I have a select control that is bound to my observable property which has the required attribute (for KO Validation).
<select data-bind="attr: { options: TypeAheadSource, value: XYZ, validationOptions: {errorElementClass: 'input-validation-error'}, typeaheadCombobox: {}"></select>
I have a custom binding associated with the select control in which I basically just call the Bootstrap Combobox Plugin. That creates a Div with an input control over the select control and hides the select control.
The knockout validation fires up when I dont select a value in the comobox and shows the error message next to the control BUT the field is not highlighted. Here is how it looks like
As you can see, the error message shows up but the input field is not highlighted.
Here is the final html that is generated when the validation fires.
<div class="combobox-container">
<input style="position:static;" type="text" autocomplete="off" data-bind="{ value: Name, validationOptions: { errorElementClass: 'input-validation-error' }" class="input-large">
<span class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"></span>
<span class="combobox-clear"><i class="icon-remove"></i></span></span>
<select data-bind="validationOptions: { errorElementClass: 'input-validation-error' }, options: TypeAheadSource, value: Name, typeaheadSimpleCombobox: { }" class="combobox input-validation-error"></select>
</div>
As you can see, the select control (which was hidden by the plugin) gets the validation error class I defined ('input-validation-error') but the input control created by the plugin does not.
That is the main issue here.
So, I thought it could be becasue the input control is not directly bound to the property. So, I tried adding the same value binding as the select control to the input control created by the plugin inside the custom binding. I also added the validationOptions binding. These changes didnt work either.
Strange thing is I also have a typeahead textbox bound to another property which uses a similar design (custom binding to create the typeahead plugin over an input control) and the validation + highlighting works perfectly on that. Here is the final html from that.
<input type="text" data-bind="value: xyz, validationOptions: { errorElementClass: 'input-validation-error' }, typeaheadTextBox: { source: $data.TypeAheadSource }" class="typeaheadValue input-mini" data-provide="customtypeahead" autocomplete="off">
Could someone tell me if I am missing any additional steps. I am sure you might need more details.
Please leave a comment and I will try to add more details.
Thanks.
I figured the issue. In case someone has the same issue, here is what I did.
Even though I setting up the value bindings on the input control created by the plugin, the bindings were applied before the control is created and so, I had to reapply the bindings specifically on the input control created by the plugin. That did the trick for me.

How do you implement the "add comment" feature used in Stackoverflow for asp.net mvc?

How do I recreate the add comment feature in Stackoverflow using mvc 3 razor (EF4)?
Here's mockup code:
<div>add comment</div>
<ul id="comments">
#foreach (var comment in Model) {
<li>#comment</li>
}
</ul>
<form method="post" id="commentForm"
action="#Url.Action("AddComment")">
#Html.TextArea("Comment", new { rows = 5, cols = 50 })
<br />
<input type="submit" value="Add Comment" />
</form>
How do I go about with the Add/Edit comments via ajax/jquery? Should it be a partial view?
I'm not sure how StackOverflow does it, but there are a few ways to achieve the same thing.
Usually, you'd write some jQuery in your page to intercept the form post and post the data using ajax instead.
You could post to a Web API or just an action that returns JSON. On the server, add the comment to whatever data store you're using and reply with either a success result or details of the saved comment (up to you). When complete, render the new entry on the client side using jQuery - in your case, just add a new li with the comment. OR
You could post to an action that returns a partial view. Save the comment, update the collection, then render the partial view. In your jQuery, you could replace the whole comments section with the new content.
It's a very broad question and there are many other ways to do it. You could use something like SignalR to push new comments from the server (to make it realtime), and you could use a JS templating framework like Knockout JS so you're only dealing with a template and an array of objects.

Why is there no intellisense in ASP.Net MVC 2.0 when assigning Model values to JavaScript?

I'm trying to add some Model properties into my JavaScript within my content page:
$(document).ready(function () {
createPager(1, <%=Model.TotalPages %>);
createUnprocessedPager(1, <%=Model.TotalUnprocessedPages %>);
});
Does anyone know if this is by design? Are you not meant to combine Model properties with JavaScript? Or is this a bug?
This works as expected. However, I do not have any Intellisense within the <% ... %> tags when actually writing the code. If I write any code within <script> tags, then there's no Intellisense. If I go directly under the tag </script> and type <% Model.... %> then boom, I have Intellisense again.
UPDATE: 22/10/2010
Just read Scott Guthrie's latest blog post and it appears this functionality is coming out soon with the up coming release of ASP.Net MVC 3 (possibly for the beta as well):
Note: Visual Studio Code/Markup
Intellisense and Colorization within
Razor files aren’t enabled yet with
the Beta earlier this month. You’ll
see this show up in a few weeks though
– and it will support full code
intellisense for HTML, JavaScript, CSS
and C#/VB code within Razor files.
There is also no syntax highlighting I think. Not sure if that's a bug or a feature, but AFAIK, combining the code this way isn't a good practice. Generally inline javascript is not a good practice, but if you go with it, combine Model properties with it, and later decide to extract the scripts into a separate js file, your code will break. Therefore, it is quite common to populate hidden fields with your Model properties and read them in your js with jQuery, e.g.:
<input type="hidden" id="valTotalPages" value="<%=Model.TotalPages %>" />
<input type="hidden" id="valTotalUnprocessedPages" value="<%=Model.TotalUnprocessedPages %>" />
...
// in js
$(document).ready(function () {
createPager(1, $("#valTotalPages").val());
createUnprocessedPager(1, $("#valTotalUnprocessedPages").val());
});
So lack of syntax highlighting and intellisense might be a bug, but might as well be a way of discouraging certain code patterns.
You will loose you Intellisense in the views inside quotes "" like attributes.
<input type="text" value="<%= DateTime.Today.ToShortDateString() %>" />
or if it appears inside of Javascript blocks.
<script type="text/javascript">
<%= DateTime.Today.ToShortDateString() %>
</script>
It is my opinion that there should be Intellisense in these scenarios, so I would say it is a bug and hope future updates to Visual Studio will address and resolve this.

Resources