How to Write JavaScript for Templated Markup? - javascript

I'm a little stuck on this.
I've been assigned changes to make to an ASP.NET project. The WebForm I'm working on needs to dynamically display and hide controls in response to user actions.
So far, so good. My approach would be to create a little JavaScript. However, on this page, the markup is part of a template for a Telerik control (which I know nothing about). I'm not sure the ramifications of this. Can I still use JavaScript for templated markup?
I tried to insert some existing JavaScript in the page. The first problem I have is my use of <%= ControlName.ClientID %>, which produces an error because the name of the control in the template is not seen to exist by ASP.NET.
Is there another way to do this, or am I just going to run into more problems?

For template controls like repeater you should hook up the javascript from isnide the itembound event. Get the control using FindControl for each row and then register the javascript from code behind. I believe your telerik control should expose something similar to the itembound event that get called for every row..

Related

AngularJS losing two way binding after JS form plugin rendering

I'm hoping someone with a better understanding of AngularJS might be able to shed some light on whats going on here.
I have a webpage with a long form. After the JS form plugin is initialized, everything in the form no longer has two way data binding. JS plugin for reference can be found here
If I remove the id link to the JS plugin, thus not applying or rendering the steps plugin, all two way data binding works as expected.
I could post a lot of code here but I'm not sure that would help. I have no problem posting code at any request.
Any ideas on why the two way data binding is losing effect after rerendering a form tag and its contents?
I was actually able to get AngularJS to work correctly with this plugin by including the plugin at the bottom of the page instead of the top. So I think the key here was to let AngularJS load up first, then the page, then the jQuery Steps plugin (at the boom of the page that uses it).
Thanks all for your comments!
Jquery library should include before angular library otherwise your site will try to use jquery instead of angular own lite jquery which will definitely break the binding.

Including a custom js file on rails_admin dashboard

I am trying to include a custom js for a custom field that depends on a google maps control, I don't want to mix html and js on a partial file, however, up to now, it appears to be the way to go.
I have checked on the wiki and the only reference about including a custom js is here but it doesn't work.
I only want to be able to organize my javascripts as usual (at assets/javascripts/) and be able to interact with my rails_admin form views. Anyone has any idea on how this should be handled?
To restate: It sounds like you are trying to keep javascript code out of view (html/erb) files.
I can recommend one way you may wish to try.
If you look at the assets/javascript directory you can see the generated javascript files that are created per controller when you are scaffolding a resource.
These files are great for keeping all the code related to the controller context in. there is another file named application.js which is great to keep global javascript routines in.
If you put tags/fields on the elements which you wish to select to bind a javascript method to you are able to keep the methods focused on finding and binding fields sharing the tag.
example:
field you wish to interact with:
Blah
your_controller_name.js:
using jquery you should be able to select the span by the data tag ( you could stored extra infor. you can then also bind methods to the span.
$("span[data-interesting='hi there']").click(function() { console.log('someone clicked the span'); })
You could use a selector that is more general and do something useful to all the matching items.
Good luck!
James.

Custom View Engine to solve the Javascript/PartialView Issue?

I have seen many questions raised around PartialViews and Javascript: the problem is a PartialView that requires Javascript, e.g. a view that renders a jqGrid:
The partial View needs a <div id="myGrid"></div>
and then some script:
<script>
$(document).ready(function(){
$('#myGrid').jqGrid( { // config params go here
});
}
</script>
The issue is how to include the PartialView without littering the page with inline tags and multiple $(document).ready tags.
We would also like to club the results from multiple RenderPartial calls into a single document.Ready() call.
And lastly we have the issue of the Javascript library files such as JQuery and JQGrid.js which should ideally be included at the bottom of the page (right before the $.ready block) and ideally only included when the appropriate PartialViews are used on the page.
In scouring the WWW it does not appear that anyone has solved this issue. A potential way might be to implement a custom View Engine. I was wondering if anyone had any alternative suggestions I may have missed?
This is a good question and it is something my team struggled with when JQuery was first released. One colleague wrote a page base class that combined all of the document ready calls into one, but it was a complete waste of time and our client's money.
There is no need to combine the $(document).ready() calls into one as they will all be called, one after the other in the order that they appear on the page. this is due to the multi-cast delegate nature of the method and it won't have a significant affect on performance. You might find your page slightly more maintainable, but maintainability is seldom an issue with jQuery as it has such concise syntax.
Could you expand on the reasons for wanting to combine them? I find a lot of developers are perfectionists and want their markup to be absolutely perfect. Rather, I find that when it is good enough for the client, when it performs adequately and displays properly, then my time is better spent delivering the next requirement. I have wasted a lot of time in the past formatting HTML that no-one will ever look at.
Any script that you want to appear at the bottom of the page should go inside the ClientScriptManager.RegisterStartupScript Method as it renders at the bottom of the page.
http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx
Edit Just noticed that your question was specific to ASP.NET MVC. My answer is more of an ASP.NET answer but in terms of the rendered html, most of my comments are still relevant. Multiple document.ready functions are not a problem.
The standard jQuery approach is to write a single script that will add behaviour to multiple elements. So, add a class to the divs that you want to contain a grid and call a function on each one:
<script language="text/javascript">
$(document).ready(function(){
$('.myGridClass').each(function(){
$(this).jqGrid( {
// config params can be determined from
//attributes added to the div element
var url = $(this).attr("data-url");
});
});
}
</script>
You only need to add this script once on your page and in your partial views you just have:
<div class="myGridClass" data-url="http://whatever-url-to-be-used"></div>
Notice the data-url attribute. This is HTML5 syntax, which will fail HTML 4 validation. It will still work in HTML 4 browsers. It only matters if you have to run your pages through html validators. And I can see you already know about HTML5
Not pretty but as regards your last point can you not send the appropriate tags as a ViewData dictionary in the action that returns the partial?

javascript templating engine that maintains focus on textboxes etc?

So I know there is a few templating engines out there, but I thought I'd ask for someones experience and reccomendation on one that can do what I'm after.
I'd previously made an (intranet) web app that used asp.net editable listviews to take input and used an update panel to make it persist the data regularly (save)
This worked ok but was alot of hackery to get focus to maintain on the ajax postback amongst other things. This is because update panels rewrite the whole section of html on each ajax postback.
So I figured for some more control and a better user experience (and quicker speeds) I'd try a jquery/javascript based templating engine. What i'm doing is making a sort of to do list (its more than that but lets just keep it simple for this example) where someoen fills out a line with an action, due date, and some other fields.
I liked John Resigs Microtemplating engine so I used that. However after working it all out it seems that it re-writes the whole javascript template each time it updates, which is just what I was trying to avoid, as it loses the users focus. I was hoping for something that would just append things onto the end - why do they need to rewrite everything?? I could do as I did with the udpate panel and use some hacking based on the current focus but I would rather avoid this and make it seamless.
am I going to have to manually code this up, or is there a decent way of doing it out there?
Resig's Microtemplating is great. However, like most client-side templating engines all it gives you is a string. How you get that string into the DOM is up to you.
Why do they need to rewrite everything?
The templating engine is not overwriting anything. Rather that is being done by you (however it is you are putting it into the DOM). For example:
var template = Template('template_id');
// The template engine simply generates a string:
var generatedHtml = template({data:'goes here'});
// The engine's work is done at this point.
// Now lets get the string into the DOM:
myElement.innerHTML = generatedHtml; // OVERWRITES
I was hoping for something that would just append things onto the end
Since you are using jQuery it is trivial to append rather than overwrite. Instead of the innerHTML line above you would use jQuery's append method:
$(myElement).append(generatedHtml);
Now, regarding your focus problem, again this is not strictly due to the template engine but rather the nature of DOM manipulation in general. The solution is to force the element you need to have focus to focus:
Lets say your template looked like this, in Resig's microtemplating parlance:
<script type="text/html" id="template_id">
Foo: <input type="text" value="<%= data %>" />
</script>
Continuing the JavaScript example of prior, you focus like this:
$(myElement).append(generatedHtml);
// Focus the just inserted text box:
$(myElement).find('input').focus();

RJS/Javascript conventions in Rails

I'm starting to look into the whole world of RJS and Prototype/jQuery in Rails and am a little bit confused. There seems to be no clear line of where to use one or the other.
Say I wanted one of the "Active, Hot, Week" tabs like the ones here on SO. When pressing one of them, I want to remove a CSS class (like "active-tab") from the one I was on and add it to the one I clicked on. Then I also want to reload the div containing the items and put in the new items into it.
Seems the class-changing thing would be easiest to do in pure javascript, say put the code in application.js and then updating the div with the content would obviously be easiest in RJS. But what should one do?
If you're comfortable with writing JavaScript then by all means use JavaScript. There's nothing wrong with that; you don't have to use RJS just because it exists. In fact you'll probably find that its abstractions get in the way.
However, if you'd rather write Ruby code that generates JavaScript, just as you write Ruby code that generates SQL in ActiveRecord Migrations, then RJS is the right tool for the job. Or you can use both: RJS for fairly simple things and then drop down to JavaScript for more complex behaviour. Use what feels right to you.
If you want to give users that ability to link to the generated page directly, then definitly go for a static page. Using AJAX breaks the back button unless you use something like Really Simple History (which is not 100% cross browser), so going the JS route with your page navigation will almost certainly cause some of your users problems.
That said, what you have discussed already would be fine, I think - just have a class change in your RJS file, then you might even find it useful to update the div contents using page.replace and a partial:
page.replace(dom_id, :partial => #page_content);

Categories

Resources