1

I have a partial view created for re-use purposes. This partial view has a dropdownlist which uses Chosen plugin. Therefore, on the partial view I reference the chosen js/css file along with some javascript code to for document ready.

It works as intended. However, now I have a page which I render the partial view upon a button click event. Users can click as many times as they want.

My concern is that duplicate js will load each time they click the button. This, perhaps, is the reason why people don't recommend adding js to Partial View directly. In my case, it needs to be there for the plug-in and manipulation within the Partial View itself. Is there a good way to check for loaded js and prevent it from loading it again in subsequent click event?

10
  • 1
    You can create a wrapper of your library, when it will load itself it will check if the library you need is loaded (there are probably some global variables from the library), if they are not present you will dynamically inject the script tag to your page, otherwise not Commented Dec 10, 2014 at 20:40
  • @VsevolodGoloviznin: This is the best answer the OP is going to get. You should just go ahead and actually add it as answer. Commented Dec 10, 2014 at 21:33
  • @NKD: To implement what Vsevolod suggests look into libraries like Require.js or Modernizr's load functionality. Commented Dec 10, 2014 at 21:34
  • @NKD In fact I would get rid of scripts in partials and just put them into the bundle and forget about this problem at all Commented Dec 10, 2014 at 21:55
  • @VsevolodGoloviznin I like your suggestion and was trying to implement it by putting it in a seperate js and load thing dynamically with $.getScript. Then I realize $.getScript doesn't work the way I expected it. Did some googling and it seems to be a known issue. Let me think about bundling a little bit. My burden is the plugin on the page. Commented Dec 10, 2014 at 22:13

2 Answers 2

0

The JavaScript and CSS files for Chosen should be included on the page when the page first loads. When the user clicks the button, make an Ajax call to include the partial. In the success callback for the AJAX request, initialize the Chosen plugin code for the dropdown lists that were just injected in the page.

Your are correct that duplicate JS and CSS files will get loaded, which is definitely something you don't want.

$.ajax(...)
    .done(function(data) {
        $("#foo")
            .html(data)
            .find("select")
            .each(function() {
                $(this).chosen({...});
            });
    });
Sign up to request clarification or add additional context in comments.

4 Comments

thank you for the suggestion. I also have documentready code on the partial page to manipulate the chosen dropdown. If I do it this way, I would end up with a long callback function (code injected after the chosen initialization).
You don't need code injected after the callback function. This code should be run as part of the callback function.
I was literately referring to code entered right after the chosen initialization line within the call back function.
it looks like your method is the only way I can get chosen to work. I guess I better off living with a long .ajax callback code than loading a bunch of references multiple times. I have one quick question tho. I have a $("select[id^='MyDropdown']").change(function () {...}); added after the $(this).chosen({..}); line. I don't understand why it doesn't work when I place it outside of the $.ajax call.
0

Extending my comment with the answer.

You can leave multiple css files, I don't think it will do any harm. As for JS files, at first you should create a wrapper file

wrapper.js

$(function() {
      if (!$().chosen) { //we do this only if chosen is not present
         var script = document.createElement('script');
         script.type = 'text/javascript';
         script.src = 'url to yor chosen library';

         $("body").append(script);
      }     
});

And then in your view you will reference this wrapper.js file instead of your chosen library path.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.