angular-ui / bootstrap

PLEASE READ THE PROJECT STATUS BELOW. Native AngularJS (Angular) directives for Bootstrap. Smaller footprint (20kB gzipped), no 3rd party JS dependencies (jQuery, bootstrap JS) required. Please read the README.md file before submitting an issue!
http://angular-ui.github.io/bootstrap/
MIT License
14.29k stars 6.73k forks source link

typeahead-popup-template-url with webpack #6494

Open randspy opened 7 years ago

randspy commented 7 years ago

Hello.

I am migrating an angular (1.6.2) app from gulp to webpack 2. I am using angular-ui-bootstrap with typeahead-popup-template-url attribute. It looks like

typeahead-popup-template-url="app/somePathHere/custom-popup.html"

How can I use it with webpack? I am getting an error message :

Error: [$compile:tpload] Failed to load template: app/somePathHere/custom-popup.html

I don't think it is a matter of path. Tried all combinations I could think of. Plus when I migrate angular components I replace

templateUrl : 'app/somePathHere/some-component.html',

with

template : require('./some-component.html'),

Could it be something similar? Is there a special syntax? I was not able to find anything on internet. And no response on stack overflow.

http://stackoverflow.com/questions/42721983/custom-template-typeahead-popup-template-url-with-webpack

Angular: 1.6.2 angular-ui-bootstrap: 2.5.0

Best regards

SharpieX commented 7 years ago

@randspy I am doing same moving to webpack and I am having same problem with datepicker-popup-template-url

No response on gitter as well

bastienmoulia commented 7 years ago

Have you try to overwrite the default template ? But this will change all typeahead not just one.

$templateCache.put("uib/template/typeahead/typeahead-popup.html", require("./some-component.html"));
WVWillHall commented 7 years ago

Here is an example where I am using a custom template in my webpack project. I am not using external files but placing the template in a script tag with a unique id.

don't mind my jade...

  script(type='text/ng-template' id='search-tab-template.html').
    <li ng-class="[{active: active, disabled: disabled}, classes]" class="uib-tab nav-item">
      <a href="javascript:void(0);" ng-click="this.active === true ? this.$parent.$parent.tabset.select(4) : select($event)" class="nav-link" uib-tab-heading-transclude>{{heading}}</a>
    </li>
uib-tab(index="0" heading="{$Flight Details$$}" template-url="search-tab-template.html")

btw, thats how you make active tabs toggleable. Took a while, so good share imo - (4) is just index of a tab that does not exist.

randspy commented 7 years ago

The first solution from @bastienmoulia works for me. I have not noticed any side effects yet. I have not tried the second one yet, but it looks interesting.

Still, it would be interesting to know if there is a no hacking solution.

SharpieX commented 7 years ago

@randspy can you tell what exactly you did kinda new with web here

randspy commented 7 years ago

It is working for me only because I use typeahead only once in the application. I hope it is clear.

angular.module('myModule').run(['$templateCache', function ($templateCache) {

    $templateCache.put(
        "uib/template/typeahead/typeahead-popup.html",
        require("./relativePathFromHereToPopUp/custom-popup.html"));
  }]);
web-dave commented 7 years ago

Hi, came over with the same problem. I have a number of TypeAhead with diffrent custom Templates. Yes I could put them in the public folder (my assets) and serve them, but i want webpack to bundle them. So how can this be managed?

tonybranfort commented 6 years ago

This is how I got mine to work but I'm hoping someone can suggest a better solution.

Add to webpack.config.js:

  ...
  plugins: [
   ...,
    new HtmlWebpackPlugin({
        template: 
          path.resolve(__dirname, 
            './src/app/client/knn-client-search-typeahead.html'),
        filename: "assets/knn-client-search-typeahead.html",
        inject: false
    }),
   ...
 ]

And in the template:

     typeahead-template-url="assets/knn-client-search-typeahead.html"
mlg87 commented 6 years ago

avoiding the templateCache with webpack will lead to better performance, so i recommend avoiding that. @tonybranfort 's solution seems like it would be similar to using the templateCache, but at least one wouldn't have all templates served via the templateCache. i think putting the template for the typeahead inline (or in the same file and then referencing) is the way to go - performance wise

mlg87 commented 6 years ago

fwiw, @WVWillHall 's solution works like a charm

BenLayet commented 5 years ago

Using @WVWillHall solution for tabs, here is a working example for typeahead:

<script type="text/ng-template" id="ticker-input-custom-template.html">
    <ul class='dropdown-menu' ng-show='isOpen() && !moveInProgress' ng-style="{top: position().top+'px', left: position().left+'px'}" role='listbox' aria-hidden='{{!isOpen()}}'>
        <li ng-repeat='match in matches track by $index' ng-class='{active: isActive($index) }' ng-mouseenter='selectActive($index)' ng-click='selectMatch($index, $event)' role='option' id='{{::match.id}}'> 
            <div uib-typeahead-match index='$index' match='match' query='query' template-url='templateUrl'></div> 
        </li> 
    </ul> 
</script>
<input type="text" ng-model="tickerInput.typedText"
       typeahead-min-length="0"
       uib-typeahead="option.ticker as option.value for option in tickerInput.options | filter:{value:$viewValue}"
       class="form-control input-text-ticker icon-search" placeholder="ticker" typeahead-popup-template-url="ticker-input-custom-template.html"
       typeahead-on-select="tickerInput.onTypeAheadSelected($item)"/>

In this example I have copied the original template inside the "text/ng-template" script, named it with a custom id id="ticker-input-custom-template.html", and just added typeahead-popup-template-url="ticker-input-custom-template.html" to the typeahead input. You can then modify the template as you wish. No need to create a separate file for the template, no need to change the template cache or do anything else in the component controller.