Call from one widget to another widget using odoo js - odoo-8

Js Xml Path : module_name-static-src-xml:
<div t-name="widget_1">
<button type="button" id = "button_1" >Click</button>
<div id = "test"> </div>
</div>
<div t-name="widget_2">
<p>Second Widget</p>
</div>
Js:
odoo.define("module_name.name", function(require) {
"use strict";
var Widget = require("web.Widget");
var Widget_Extend = Widget.extend({
template: "widget_1",
start: function() {
var self = this;
$(document).ready(function(){
setTimeout(function(){
$(document).on("click", "#button_1", function() {
var widget_call = '';
widget_call = '<div id ="test"></div>'
widget_call + = '<t t-call="widget_2"/>'
$('#test').html(widget_call);
});
});
});
}
});
core.action_registry.add("module_name.name", Widget_Extend);
});
Note:
I have tried to call "widget_2" using js but i could not get what i expect. I am not sure this the way to call the widget but i have tried a lot. If any one have some other way to call the 2nd widget from 1st widget using js kindly let me know.
Anticipating all kind of information about this problem.
Thanks.

you can inherited a widget to another widget As an example, it may look like this:
// in file a.js
odoo.define('module.A', function (require) {
"use strict";
var A = ...;
return A;
});
// in file b.js
odoo.define('module.B', function (require) {
"use strict";
var A = require('module.A');
var B = ...; // something that involves A
return B;
});

Related

Event on node not calling the function when using the render function

I'm trying to render dynamic charts and therefore need to use the mermaid.render function. But using click does not work when the code isn't entered in a static way as you can see in the snippet bellow:
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({
theme: "base",
startOnLoad: false,
securityLevel: 'loose'
});
</script>
<p onclick="CreateGraph()">CreateGraph</p>
<div class="mermaid"></div>
<script>
var CreateGraph = function() {
var gdata = `
flowchart
a-->b
click a callback
`;
var div = document.getElementsByClassName("mermaid")[0];
mermaid.render("graphDiv", gdata, (svgCode, bindFunctions) => {
div.innerHTML = svgCode;
});
};
var callback = function() {
alert('A callback was triggered');
};
</script>
But if you were to put the content of gdata and put directly inside the mermaid div (as well as setting startOnLoad to true) then everything would work as expected.
Does anyone have a clue on what's happening or maybe a fix?
Thank you!
Alternative. Use href to include the function call in the parameter.
var gdata = `
flowchart
a-->b
click a href "javascript:callback();"
`;
For the click events to work, after updating the innerHTML of the element you must also set the bindFunctions.
element = document.querySelector('#some_id');
const insertSvg = function (svgCode, bindFunctions) {
element.innerHTML = svgCode;
bindFunctions(element);
};
const graphDefinition = 'graph TB\na-->b';
// Render the graph
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);

does not capture a class in ajax

I'm having trouble changing a class with ajax, it works with the boton class but not with the boton_clic_sin class, please, someone who can help me. Thank you
$(document).ready(function() {
$('.btnguardar').on('click', function(e) {
e.preventDefault();
var $container = $(this).closest(".container");
var id_oferta = $container.find(".id_oferta").val();
var url_img = $container.find(".url_img").val();
var $boton = $(this).closest('.boton');
var $boton_clic_sin = $(this).closest('.boton_clic_sin');
$.ajax({
type: "POST",
url: "app/ofertasguardadasController.php",
data: {
id_oferta,
url_img},
success: function(r) {
if (r==1) {
$('.aviso').empty();
$('.aviso').append('Se agrego a la lista Ver lista').fadeIn("fast");
$('.aviso').fadeOut(7000);
$boton.addClass('deshabilita');
$boton.attr('disabled', 'disabled');
$boton_clic_sin.addClass('.habilita');
$('.lista').html("Ver lista").fadeIn("slow");
$('.title_lista').html("Agregado a la lista").fadeIn("slow");
}
}
});
});
});
Html
<span class="boton_clic_sin">♥</span>
<button id="btnguardar" class="boton btnguardar">♥</button>
If your span is located just before your button you can use prev() to get that element and use toggleClass to add or remove the added class.
Demo Code(I have removed some code which was not needed ) :
$('.btnguardar').on('click', function(e) {
//find button prev element ->span
var $boton_clic_sin = $(this).prev();
//use toggle to add or remove class
$boton_clic_sin.toggleClass('habilita');
});
.habilita {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="boton_clic_sin">♥</span>
<button id="btnguardar" class="boton btnguardar">♥</button>
You can change a class to your span element by using this $('.boton_clic_sin').addClass('habilita'); and $('.boton_clic_sin').removeClass('habilita');
Instead of doing this stuff var $boton_clic_sin = $(this).closest('.boton_clic_sin');, and a toggleClass
e.g.
$('.btnguardar').bind('click', function(e) {
if($('.boton_clic_sin').hasClass('habilita')){
$('.boton_clic_sin').removeClass('habilita');
}else{
$('.boton_clic_sin').addClass('habilita');
}
});
.habilita{
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="boton_clic_sin">♥</span>
<button id="btnguardar" class="boton btnguardar">♥</button>

Product filter in Ajax will work in Wordpress

I have this code in Ajax but I want this to work in Wordpress. I just want to make a product filter in Ajax that will work in WordPress. I am just new to this. Any help and idea please?
<script>
$(document).ready(function(){
filter_data();
function filter_data()
{
$('.filter_data').html('<div id="loading" style="" ></div>');
var action = 'fetch_data';
var minimum_price = $('#hidden_minimum_price').val();
var maximum_price = $('#hidden_maximum_price').val();
var brand = get_filter('brand');
var ram = get_filter('ram');
var storage = get_filter('storage');
$.ajax({
url:"fetch_data.php",
method:"POST",
data:{action:action, minimum_price:minimum_price, maximum_price:maximum_price, brand:brand, ram:ram, storage:storage},
success:function(data){
$('.filter_data').html(data);
}
});
}
add_action( 'wp_ajax_action', 'filter_data' );
add_action( 'wp_ajax_action', 'filter_data' );
function get_filter(class_name)
{
var filter = [];
$('.'+class_name+':checked').each(function(){
filter.push($(this).val());
});
return filter;
}
$('.common_selector').click(function(){
filter_data();
});
$('#price_range').slider({
range:true,
min:1000,
max:65000,
values:[1000, 65000],
step:500,
stop:function(event, ui)
{
$('#price_show').html(ui.values[0] + ' - ' + ui.values[1]);
$('#hidden_minimum_price').val(ui.values[0]);
$('#hidden_maximum_price').val(ui.values[1]);
filter_data();
}
});
});
</script>
How can I make an ajax call in wordpress without use of plugin?
Ajax code
<script type="text/javascript">
function filter_data(){
$('.filter_data').html('<div id="loading" style="" ></div>');
var action = 'fetch_data';
var minimum_price = $('#hidden_minimum_price').val();
var maximum_price = $('#hidden_maximum_price').val();
var brand = get_filter('brand');
var ram = get_filter('ram');
var storage = get_filter('storage');
var data = {
action:action, minimum_price:minimum_price,
maximum_price:maximum_price, brand:brand, ram:ram,
storage:storage
};
$.post('/wp-admin/admin-ajax.php',data,function(response){
$('.filter_data').html(data);
});
}
</script>
In you function.php file
add_action('wp_ajax_fetch_data','filter_data'); // for loggedin user
add_action('wp_ajax_nopriv_fetch_data', 'filter_data'); // for non loggedin user
function filter_data()
{
$minimum_price = $_POST['minimum_price'];
$maximum_price = $_POST['maximum_price'];
$brand= $_POST['brand'];
$ram= $_POST['ram'];
$storage= $_POST['storage'];
// here your product filter code
}

can.Model with can.view to populate DOM dynamically or once records are loaded

There is the following can.Model:
var CaseModel = can.Model.extend({
findAll: function(args){
var def = $.Deferred();
args.sobject.retrieve(args.criteria, function(err, records) {//records should be populated into view
if(err) def.reject(err);
else def.resolve(records);
});
return def;
}}, {});
How should I implement the can.Control with init method to populate can.view with deffered=CaseModel.findAll({sobject: new SObjectModel.Case()}) like here:
this.element.html(can.view('recipes', Deffered));
and how these records are looped in mustache template:
{{#each ???? }}
Thanks
Here is an example of how to do it with deferreds:
var CaseModel = can.Model.extend({
findAll: function(args){
var def = $.Deferred();
setTimeout(function () {
console.log('time');
def.resolve([{name: 'sam'}]);
}, 1000);
return def.promise();
}}, {});
var Control = can.Control({
init: function (ele, options) {
var self = this;
var pro = CaseModel.findAll({});
can.view('view', {records: pro})
.then(function(frag) {
self.element.html(frag);
});
}
});
var control = new Control('.app');
<script type="text/mustache" id="view">
VIEW
<ul>
{{#each records}}
<li>
{{name}}
</li>
{{/each}}
</ul>
</script>
And here is a demo
http://jsbin.com/kedih/1/edit
You should be able to adapt this to include your args.sobject.retrieve instead of the setTimeout in the example.

event click Handlebars

Using Handlebars and OpenDatabase i have small problem. When you click on a link and nothing happens
my JS.
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM exhibition', [], function (tx, results) {
var source = document.querySelector("#exhibition-template").innerHTML;
var data = [];
template = Handlebars.compile(source);
for(var i=0;i < results.rows.length; i++) {
data.push(results.rows.item(i));
}
var context = (data);
if (language == 'pl')
{
var html = template({o:context,language_pl:true});
}else{
var html = template({o:context,language_en:true});
}
document.querySelector("#template").innerHTML = html;
}, null);
$(".exl").on("click", function(){
alert('event click!');
});
});
and my html
{{#each o}}
<a href='' class='exl'>{{name_pl}}</a>
{{/each}}
You're probably binding events before the generated DOM is appended to the page. So, you can either wait for Handlebars template to be rendered (In your case this mean binding event in the callback from tx.executeSql). Or you can use event delegation with jQuery:
$(document).on("click", ".exl", function(){
alert('event click!');
});

Resources