How to call the website side widget in odoo - javascript

This is my file which was contain template 'website_fb.fb_shared_post'
Qweb.add_template('website_fb_redertemplate.xml');
Below code through create a website side widget so now if call this widget then how to do.
I refer the Odoo documentation but nothing to understandable for me so please help me.
var RenderTemplate = Widget.extend({
template: 'website_fb.fb_shared_post',
events: {
// DO some code
},
init: function (el) {
// DO some code
},
start: function () {
// DO some code
}
});

First, when you create widget it will automatically render above XML file that you mention in the first line so below line render another widget template XML file
$(Qweb.render("fb_shared_post", {'res':'Hello'})).prependTo('<TemplateDivID or Class>');

Related

extend Widget's init method in odoo 13

I'm trying to extend the widget's init method to make a simple console.log when the page is loaded, but it doesn't work, what can be a correct way to do this?
odoo.define('lliege_pdt_main.pdt_maps', function (require) {
var Widget = require('web.Widget');
var pdt_maps = Widget.extend({
init: function (parent) {
console.log("test");
this._super(parent);
},
});
return pdt_maps;
});
In your case you do not want to inherit the widget in the classical sense. You want to modify the parent itself. This can be done with include instead of extend:
var pdt_maps = Widget.include({
init: function (parent) {
console.log("test");
this._super(parent);
},
});
Don't forget to debug in assets debug (gorilla) mode. Here is the official documentation on patching a JS class like this.

ASP .NET Core how to generate razor Urls in javascript files?

I have a lot of javascript functions that i want to separate by logic into multiple javascript files. The problem is that all my ajax functions urls are generated by razor.
$.get('#Url.Page("Index","ViewReferenceRecordsPartial")', { productionRecordId: productionRecordId }, function (response) {
$('#details').html(response)
stopLoading(element);
})
How can i keep my function like this on a js file?
UPDATE
Here is a temporary solution until there is a more maintainable solution which is pretty quick to do using data attributes.
in a js file i have this function
function viewReferenceRecords(element, productionRecordId) {
startLoading(element);
$.get($(element).data('url'), { productionRecordId: productionRecordId }, function (response) {
$('#details').html(response)
stopLoading(element);
})
}
on my table I have a button that calls this function
<button data-url="#Url.Page("Index","ViewReferenceRecordsPartial")" onclick="viewReferenceRecords(this, #Model.Id)">Details</button>
it's very simple and easy, just store the Url generated by razor on a data attribute on the element and pass it to the function in the js file and retrieve the string generated on the data attribute.
I typically use the revealing module pattern for things like this. You can read about it here: https://gist.github.com/zcaceres/bb0eec99c02dda6aac0e041d0d4d7bf2
It's sort of like namespacing, but in JavaScript. Then you can pass in parameters. I would do it like this:
JS file
var MeaningfulModuleName = MeaningfulModuleName || (function () {
var _partialUrl = null;
return {
init: function (partialUrl) { _partialUrl = partialUrl; },
loadPartial: function (targetSelector, productionRecordId) {
$.get(_partialUrl, { productionRecordId: productionRecordId }, function (response) {
$(targetSelector).html(response);
// ...
}
}
}
});
Then in your razor view, you create a script tag at the bottom of the page with this:
<script type="text/javascript">
$(document).ready(() = {
MeaningfulModuleName.init(#'Url.Page("Index", "ViewReferenceRecordsPartial")');
// Some event occurs
MeaningfulModuleName.loadPartial('#details', productionRecordId);
}
</script>
Where MeaningfulModuleName is whatever name makes sense to you for this particular JS file.
This solves it for me, and I think it makes the JS look a bit cleaner, too. Everything is organized into "modules". Also, I apologize if the code doesn't work perfectly. I wrote this on my phone. :)

Meteor callback on some template render

In my meteor project, I have a code like this:
baz = function() {
// some jQuery add/remove class here...
};
Template.foo.onRendered(function() {
baz();
});
Template.bar.onRendered(function() {
baz();
});
Template.qux.onRendered(function() {
// no baz() call
});
Is there a better way to accomplish this task without repeat baz(); on some template render?
Meteor 1.2.1 allows you to run a global onRendered() function via the following code:
Template.onRendered(function() {
var that = this; //pass that into baz() if you need it
Deps.afterFlush(function() {
console.log('baz');
baz();
});
});
If that doesn't fit your needs, and you want it on every page, just use onRendered() within some common template like the menu or page header, however this will not guarantee that the HTML you are attempting to alter with JQuery will be rendered.
Similar to #Brett answer, you could also use the Template.body.onRendered(function(){..
Each onRendered function is executed only once per template (when it loads).
The body (implicit) template, being the main container(parent) for the other templates(childs) will be executed on each page request.

Order Levels on Underscore Templates, making sure data form Backbone Collection loads in set order?

I have an Underscore.JS template loading in basic text data from my database. These load into two div tags. But I think (I am not sure here, please correct me if I am wrong), that depending on what table Backbone gets first depends on the order of which these div tags are displayed in.
So (a), I have come up with a answer, I just wanted to know weather or not this was the best way of doing it by 'chaining' (if that is the right way of calling it) the success calls, within the same Backbone View, this loads both divs into the same Underscore template. So this is my code currently,
var TextEditView = Backbone.View.extend({
inititalize: function() {
this.listenTo(this.BasicTextModel, "change", this.render);
},
el: $(".BasicTextTemplate"), //Template loader placeholder
render: function() {
var that = this;
var AboutText = new TextAboutCollection(); //Get About page text
var HomeText = new TextHomeCollection(); //Get Home page text
HomeText.fetch({
success: function(Text) {
var GetHomeTxt = _.template( $('script.BasicText').html(), { Text: Text.toJSON() } ); //Load About text into template
that.$el.append(GetHomeTxt);
that.trigger('ChangeTxt', that);
AboutText.fetch({
success: function(Text) {
var GetAboutTxt = _.template( $('script.BasicText').html(), { Text: Text.toJSON() } ); //Load About text into template
that.$el.append(GetAboutTxt);
that.trigger('ChangeTxt', that);
} //End of Success Call to AboutText
}); //End of .fetch for AboutText
}}); //End of Success & .fetch calls for HomeText
} //End of render view function
}); //End of TextEditView
The AboutText is only loaded after the success call for hometext fetch is done, right? Even if I do not get this 100%, it does seem to work for now.
And (b), is there a simple way of adding a 'level' or ID to each div tag making sure Underscore loads each tag in the order I want? Or do I have this completely wrong and should load both these Collections into their own view pointing to there own template? If so I do not understand the point of the template? The way I have them now, I only have the one template that I have re-used!
Please if I am wrong, please correct me
Thanks,
EDIT of the EDIT:
model = new Model({_id:id})
var fetched = model.fetch();
// wait for the model to be fetched
$.when(fetched).then(function(){
view = new View({model:model})
app.content.show(view)
});
from https://stackoverflow.com/a/13601074/2535516
EDIT :
This refers about the comment.
About building code, i think u refer as organization of a backbone project (correct me if i'm wrong). If so, the way i am doing is write my code by module. A module is basically : a BackboneModel/Collection, View, and underscore template.
Architecture :
/
main.js
About/
-- about.html <-- contains the underscore template
-- aboutView.js
-- aboutModel.js
-- aboutCollection.js
Menu/
-- menu.html
-- menuView.js
-- menuModel.js
-- menuCollection.js
And i load it through an AMD lib, mostly require.js
This architecture is a personal, what you will mostly see is :
/
main.js
View/
-- about.js
-- menu.js
Model/
-- aboutModel.js
-- menuModel.js
Collection/
-- aboutCollection.js
-- menuCollection.js
A good example is the TODOMvc architecture
Your code will work, but this is not very readable and will go worse if you'll have to add some fetch :
HomeText.fetch({
AboutText.fetch({
Module1Text.fetch({
Module2Text.fetch({
});
});
});
});
This is call the pyramid of doom.
To avoid this, use promises.
As a note, jquery do promises

using requirejs to only load jquery plugins on user interaction

I am starting to play with require js / modular development for the first time and am liking what I see.
What I am trying to achieve is basically only load certain custom jQ modules when needed. My main goal is page performance. At present I am only loading require.js (which in turns loads jQ async) then other jQ code/plugins only fire on user interaction.
Would the following code be considered good/bad practice? Is there anything anyone would change? (super basic example below)
MAIN.JS
require.config({
paths: {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min"
}
});
require(["jquery"], function($) {
// overlay plugin
$("a").on("click", function(e){
var self = this;
require(["overlay"], function (overlay) {
overlay.init(self);
});
e.preventDefault();
});
});
OVERLAY.JS
define(function () {
return {
init: function(self) {
$.ajax({
url: self.href,
success: function (data) {
$("#results").html($(data).filter('#details').html());
},
dataType: 'html'
});
$('#results').fadeIn();
}
}
});
Cheers,
Adi.
Your method of loading overlay is a correct use of require, however a couple of things:
Overlay.js should list jQuery as a dependency. Ensure your modules have all the code they need to run. In this case it's fine (as you're grabbing jQuery in the require) but say you used document.addEventListener to attach your click then you're no longer sure jQuery will be available for use by the $.ajax. It's nice to know your modules ask for everything they need rather than getting it by luck.
One rule I try to follow is to keep all my DOM related stuff in main. So for example:
Overlay
// Example code, and not complete
define(function(require) {
var $ = require('jquery');
return {
init: function(elements) {
this.trigger = $(elements.trigger);
this.target = $(elements.target);
this.trigger.on('click', this.someEvent.bind(this));
},
someEvent: function() {
this.getAjax();
}
}
});
And then in main.js just pass in the DOM elements
require(['overlay'], function(overlay) {
overlay.init({
trigger: 'a',
target: '#results'
})
});
Keeping the DOM elements separate and in one place makes updating them breeze. You could also pass in an options object for other things (such as class names) much like a jQuery plugin does.
Finally, in your example code your $('#results').fadeIn(); is outside the success callback and would run immediately.

Categories