how to implement onpopstate? confused after reading so many things - ajax

I am loading content using AJAX, and changing URL by using pushastate, below is my code, can anybody tell me how to implement onpopstate to enable back button in my case.
HTML
<div id="tabs" style="margin:1px 0px 0px 15px;">
<ul class="tabs-ul">
<li id="boardLi" class="current-tab"><a class="current-tab" href="board.jsp">Board</a></li>
<li id="aboutLi">Info</li>
<li id="photoLi">Photo Albums</li>
</ul>
</div>
JS
$(document).ready(function() {
function loadContent(path,c,pageName){
$.ajax({ url: path, success: function(html) {
$('#ajax-content').empty().append(html);
window.history.pushState({path:''},'',pageName+'?tab='+c);
}
});
}
function checkC(target){
var c='';
if(target=='aboutme.jsp')
{c='info';}
else if(target=='board.jsp')
{c='board';}
else if(target=='photo.jsp')
{c='photo';}
else if(target=='tab.jsp')
{c='ht';}
return c;
}
$(".tabs-ul li a").on('click', function(e) {
e.preventDefault();
$('#ajax-content').empty().append("<div id='loading'><img src='images/preloader.gif' alt='Loading' /></div>");
$('.tabs-ul li a').removeClass('current-tab');
$('.tabs-ul li').removeClass('current-tab');
$(this).addClass('current-tab');
$(this).parent().addClass('current-tab');
var url = window.location.pathname;
var pageName = url.substring(url.lastIndexOf('/') + 1);
var target=$(this).attr('href');
var c=checkC(target);
loadContent(target,c,pageName);
return false;
});
var loaded = false;
window.onpopstate = function(e) {
if (!loaded) {
loaded = true;
return;
} else {
alert(window.loacation.back().pathname);
loadContent();
}
};
});
When user clicks on link, first of all I am adding removing class for loading then I am getting URL and getting the page name from that URL(saved in 'pageName'), 'target' is href attr of clicked link and 'c' is the value I will be showing in url(for example, example.com/profile.jsp?tab=info, here if the href is info.jsp then 'c' would be info), finally I am calling 'loadContent' function which loads ajax content and changes URL using pushState.

Related

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>

How to make an id= from an XML call give a link to what its calling?

One of my API calls gives a youtube link and I want the link to be clickable and open on another tab, but nothing is working
this is mode code HTML:
//the id produces a youtube link that that can be clicked, but if I add the id to the href, then it wont work.
<a href="" target="_blank">
<p id="strYoutube2"></p>
</a>
my js code:
//this is my XML call, if theres another .link function other than .innerXML for the youtube link, maybe that can be the issue, but I cant find anything online.
function getPosts() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.themealdb.com/api/json/v1/1/random.php', true);
console.log(xhr.readyState);
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = JSON.parse(xhr.responseText);
console.log('response below:')
console.log(response);
console.log(response.meals[0].strMealThumb);
document.getElementById('strMeal').innerText = response.meals[0].strMeal
document.getElementById('strCategory').innerText = response.meals[0].strCategory
document.getElementById('strArea').innerText = response.meals[0].strArea
document.getElementById('strTags').innerText = response.meals[0].strTags
document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
document.getElementById('strMealThumb').src = response.meals[0].strMealThumb
}
}
}
The HTML element with id strYoutube does NOT exist in you provided code:
document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
For achieve what you're triyng to do, you can change your code as follows:
Check that I set an img HTML element with a predefined width and height.
Check the working jsfiddle here too:
// This is your function for get the posts of the given API URL.
function getPosts() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.themealdb.com/api/json/v1/1/random.php', true);
console.log(xhr.readyState);
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = JSON.parse(xhr.responseText);
console.log('response below:')
console.log(response);
console.log(response.meals[0].strMealThumb);
// Comented due these HTML elements aren't here.
//document.getElementById('strMeal').innerText = response.meals[0].strMeal
//document.getElementById('strCategory').innerText = response.meals[0].strCategory
//document.getElementById('strArea').innerText = response.meals[0].strArea
//document.getElementById('strTags').innerText = response.meals[0].strTags
//document.getElementById('strYoutube').innerHTML = response.meals[0].strYoutube
//document.getElementById('strMealThumb').src = response.meals[0].strMealThumb
// Here I set the values to your HTML elements:
// "strYoutube" is the HTML anchor element "<a href>".
document.getElementById('strYoutube').href = response.meals[0].strYoutube;
// "myImg" is the HTML image element "<img src>".
document.getElementById('myImg').src = "https://www.themealdb.com/images/media/meals/ysqupp1511640538.jpg";
document.getElementById('myImg').alt = response.meals[0].strMeal;
document.getElementById('myImg').title = response.meals[0].strMeal;
}
}
}
// Call your function and set the values ion the HTML elements:
getPosts();
<a href="" target="_blank" id="strYoutube">
<p id="strYoutube2">
<img src="#" id="myImg" alt="image" title="" style="width: 150px; height: 150px;" />
</p>
</a>

Call from one widget to another widget using odoo js

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;
});

jquery hide div on server response

I have this jquery script for showing a div on server response
function valLogin(){
//testing regular expression
var var1 = $("#username").val();
var var2 = $("#password").val();
$.ajax({ //Make the Ajax Request
type: "POST",
url: "login.php", //file name
data: "username="+var1+"&password="+var2, //data
success: function(server_response){
$("#logform").ajaxComplete(function(event, request){
if (server_response == 1){
window.location.reload();
return false
} else if (server_response == 0){
$('#logmess').show;
return false
}
}); //ajaxcomplete
}
}); //$.ajax
}
<div id="logmess" style="display:none;" align="right">Wrong UserID or password! <img src="/img/close.gif" onClick="$('#logmess').hide();" style="cursor:pointer;"/></div>
if server_response==0 then I show the div. I have a close button inside div with onClick="$('#logmess').hide();". the div is hiding but is appearing again after few seconds and this happens again and again. why the div is appearing again? Is something in my script that makes a loop?

how to load a partial view inside an anchor tag which has been generated via Ajax

I have a form with a dropdownlist. When selecting an option, I make an ajax call to dynamically add a list of links in the view. When I click on one of the links, I want to update the existing page with a partial view returned by the PostListSubCategory() method.
Currently, clicking on one of the links does a redirect and shows the partial view in a new page. How can I update the the existing page?
<script language="javascript" type="text/javascript">
function GetSubCategory(_categoryId) {
var procemessage = "<a='0'> Please wait...</a>";
$("#SubCategoryID").html(procemessage).show();
var url = "/Posts/GetSubCategoryById/";
$.ajax({
url: url,
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
var markup = "";
for (var x = 0; x < data.length; x++) {
var num = data[x].Text;
markup += "<a href='/posts/postlistsubcategory?subcategoryid=" + data[x].Text + "'>" + data[x].Text + "</a><br />";
// markup += "<a href=" + Url.Action("postlistsubcategory", new { subcategoryid = num });
}
$("#SubCategoryID").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
$.ajax({
url: "/Posts/PostListCategory",
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
$("#postList").html(data).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
</script>
#using (Html.BeginForm())
{
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel, "CategoryId", "Name"), new { #id = "ddlcategory", #style = "width:200px;", #onchange = "javascript:GetSubCategory(this.value);" })
<br />
<br />
<div id="SubCategoryID" name="SubCategoryID" style="width: 200px"></div>
<br /><br />
}
In the controller
public PartialViewResult PostListSubCategory(string subcategoryid)
{
if (subcategoryid == null)
{
return PartialView(db.Posts.ToList());
}
return PartialView("PostList", db.Posts.Include(i => i.SubCategory).Where(p => p.SubCategory.Name == subcategoryid));
}
You currently dyamically generating links with an href attribute so clicking on them will do a redirect. You need to handle the click event of those links using event delegation and then use ajax to update the existing DOM. There a some other bad practices in your code and I suggest you use the following
#using (Html.BeginForm())
{
// no need to override the id attribute and use Unobtrusive Javascript (don't pollute markup with behavior)
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel,"CategoryId", "Name"))
}
<div id="SubCategoryID"></div> // no point adding a name attribute
<div id="postList"></div>
var subcategories = $('#SubCategoryID');
$('#CategoryModel').change(function() {
var url = '#Url.Action("GetSubCategoryById", "Posts")'; // don't hard code url's
var category = $(this).val();
subcategories.empty(); // clear any existing links
$.post(url, { categoryid: category }, function(data) { // this could be a GET?
$.each(data, function(index, item) {
subcategories.append($('<a></a>').text(item).attr('href','#').addClass('subcategory')); // see note below
});
});
});
Note: Since your ajax only needs one property to generate the links (the value to display in the link), then your GetSubCategoryById() should be returning IEnumerable<string> not a collection of complex objects (you current code suggest your returning other data which you never use). If you do need to return a collection of objects, then change the above to use .text(item.Text). The above code will generate
.....
for each item you return. Then add an additional script to handle the .click() event of the links (since the links are dynamically added, you need event delegation using the .on() method)
var posts = $('#postList');
$('#SubCategoryID').on('click', '.subcategory', function() {
var url = '#Url.Action("postlistsubcategory", "posts")';
var subcategory = $(this).text();
posts.load(url, { subcategoryid: subcategory });
});

Resources