Refresh attribute value after html() with ajax - javascript

I am making start/pause button that works like this:
var btns = document.querySelectorAll(".repairToggle");
for (i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", manageOrderStatus);
}
function manageOrderStatus() {
var func = this.getAttribute("func");
var btn = this;
var endpoint = "{% url 'mtn:ajax_repair_toggle' %}";
$.ajax({
url: endpoint,
type: "GET",
data: {
'func': func,
},
success: function (data) {
$(btn).html(data);
}
});
}
I have start and stop buttons stored in separate html files:
work_order_start.html:
<div type="button" class="repairToggle" func="start">
<svg>...</svg>
</div>
work_order_pause.html:
<div type="button" class="repairToggle" func="stop">
<svg>...</svg>
</div>
In view i render one of the buttons based on the value of func attribute:
def repair_toggle(request):
...
func = request.GET.get('func')
if func == 'stop':
return render(request, 'mtn/work_order_start.html')
else:
return render(request, 'mtn/work_order_pause.html')
The problem is it only works once. After the first click it keeps executing ajax call but it sends the same old func value in request. How do i fix that?
UPDATE:
I figured out the problem. $(btn).html(data); only replaces the svg element. So the func stays the same. If i do this instead:
<div type="button" class="repairToggle">
<svg id='funcButton' func="stop">
</div>
How do i get func out of svg. I tried this.getElementById('funcButton').getAttribute("func"); but it doesn't work.

You are inserting the button inside the original button.
Change work_order_pause.html and work_order_start.html to only contain the svg and add in success function :
if(func == "start"){
this.setAttribute("func", "stop")
}
else{
this.setAttribute("func", "start")
}

Related

How can i assing a different class after a success ajax response

I'm working in a net core app, i made a HttpPost function to know if an user marked like.
This is the function code:
var likesCancion = (from likesCanc in _context.table
where likesCanc.SongId == idCancion && likesCanc.UserId == idUser
select likesCanc.Likes).FirstOrDefault();
if (likesCancion == 1)
{
return 1;
}
else
{
return 0;
}
I have this:
<div class="col-3 col-sm-2 col-md-2">
<i class="far fa-heart" id="heart" data-idAudio = #song.Id>
<span class="badge" >#song.Likes</span>
</i>
</div>
This is the <div> that I want to change at the start of the page if the user liked it or not.
The #song.Likes its data filled from the database.
I made an ajax request inside a for loop and get the respond of my HttpPost function:
const iconosCorazon = document.querySelectorAll('#heart');
setTimeout(function () {
let idUser = $('#inputidUsuario').val();
function makeRequest(i)
{
$.ajax({
type: "POST",
url: "checkHeart",
data: { idCancion: i, idUser: idUser },
dataType: "text",
success: function (msg) {
console.log(msg);
**if (msg == 1) {
$('.fa-heart').removeClass("far text-dark");
$('.fa-heart').addClass("fa text-danger");
}
else
{
$('.fa-heart').removeClass("fa text-danger");
$('.fa-heart').addClass("far fa-heart");
}**
},
error: function (req, status, error) {
console.log(msg);
}
});
}
for (var i=0;i<iconosCorazon.length;i++) {
let idCancion = iconosCorazon[i].getAttribute('data-idAudio');
makeRequest(idCancion);
}
I want to assign the css class to the correct element coming from the function result.
The issue here its that ajax execute all the elements at once and change the classes only with the last lopped element. So the question is how can i assign the rigth class to each div element. eg: If result == 1 paint red, if result == 0 paint other color.
Sorry for my bad english
Im trying to make this code works
You should use $(".fa-heart:eq(index)") to locate the each element with same class name. Sample code below:
$(".div_test:eq(0)").css("border","2px solid yellow");
Test Result:

How to get return of one function with parameter in other function in Javascript

I am new to JavaScript and kind of stuck at this place
function onView(data){
var item_size = data;
return item_size;
}
I have this function with parameter passing through HTML input, i want to use return of this function in another function
function onRegisterInput(){
var y= onView(data);
}
onRegisterInput is called onclick Button, i want to take return value of onView function as var y.
How can i do this ??
Everytime i click button onRegisterInput() function is called but my debugger shows data is undefined. Please help. Thanks in advance.
As you can see in onView, it takes data as function parameter, however you don't give it any parameter in your call var y= onView();. From my understanding, onView get's triggered when a button is clicked, so I'd suggest you save your value in a global variable so you can use it across functions
There are 2 ways for you to get the data in your button click callback.
Get data from the DOM
There are different ways to keep data inside the DOM, but data-* attributes are popular:
function testMe(event, button) {
const magicNumber = button.getAttribute('data-magic-number');
document.getElementById('result1').innerHTML = magicNumber;
}
function testMe2(event, button) {
const magicNumber = document.getElementById('magic2').getAttribute('data-magic-number');
document.getElementById('result2').innerHTML = magicNumber;
}
.test {
padding: 4px;
}
<div class="test">
<button id="button1" data-magic-number="123456789" onclick="testMe(event, this)">Button 123456789</button>
<div id="result1"></div>
</div>
<div class="test">
<span data-magic-number="987654321" id="magic2">Click this: </span><button id="button2" onclick="testMe2()">Button 987654321</button>
<div id="result2"></div>
</div>
Another option is to keep data inside the JS
let myMagicNumber = 1;
let resultDiv = document.getElementById('result');
function showNumber() {
resultDiv.innerText = myMagicNumber;
}
function incNumber() {
myMagicNumber++;
showNumber();
}
function decNumber() {
myMagicNumber--;
showNumber();
}
<div>
<button onclick="showNumber()">Show</button>
<button onclick="incNumber()">+1</button>
<button onclick="decNumber()">-1</button>
</div>
<div id="result">
</div>
Let's return to your example
function onView(data) {
// Some data processing
// We will return data length for example
return (typeof data === 'string' ? data.length : 0);
}
function onRegisterInput() {
// Button click
let data = document.getElementById('name').value;
if (data != '') {
var y = onView(data);
document.getElementById('result').innerText = 'Name: ' + data + ', length: ' + y;
} else {
document.getElementById('result').innerText = 'Enter your name';
}
}
<div>
<label>Name: <input type="text" id="name"/></label>
<button onclick="onRegisterInput()">Register</button>
</div>
<div id="result"></div>

Ajax search doesn't work the second time (ASP.NET MVC)

I have a problem changing items after searching.
I looked at similar threads but found no solution there :(
It looks like the first time the page loads well - the first time the entire Index.cshtml page is loaded which contains a collection of books in the selected category.
There is a search engine on the page - after searching for "manual" - ajax correctly replaces elements with those containing "manual" in the name.
Then when I enter something into the search engine a second time (for example "exercises") - the content of the page does not change any more.
I tried to debug and I see that new items are correctly downloaded from the database - the condition "if (Request.IsAjaxRequest ())" is true and the items are passed to partial view - there the "foreach" loop goes through them. Unfortunately, after _Partial, nothing happens.
I can't find a mistake - the strangest thing is that the first ajax call works fine - only the second (and subsequent) bad.
CatalogController.cs
public ActionResult Index(string categoryName = null, string searchQuery = null)
{
if (categoryName == null)
categoryName = (db.Categories.Find(1)).Name;
var category = db.Categories.Include("Books").Where(x => x.Name.ToLower() == categoryName).Single();
var books = category.Books.Where(x => (searchQuery == null || x.Title.ToLower().Contains(searchQuery.ToLower()) || x.SubTitle.ToLower().Contains(searchQuery.ToLower()) || x.Level.ToLower().Contains(searchQuery.ToLower())) && !x.Inaccessible);
if (Request.IsAjaxRequest())
return PartialView("_PartialBooksList", books);
else
return View(books);
}
Index.cshtml
<form class="o-search-form" id="search-form" method="get" data-ajax="true" data-ajax-target="#booksList">
<input class="o-search-input" id="search-filter" type="search" name="searchQuery" data-autocomplete-source="#Url.Action("SearchTips")" placeholder="Search" />
<input class="o-search-submit" type="submit" value="" />
</form>
<div class="row" id="booksList">
#Html.Partial("_PartialBooksList")
</div>
#section Scripts
{
<script src="~/Scripts/jquery-3.5.0.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.js"></script>
<script>
$(function () {
var setupAutoComplete = function () {
var $input = $(this);
var options =
{
source: $input.attr("data-autocomplete-source"),
select: function (event, ui) {
$input = $(this);
$input.val(ui.item.label);
var $form = $input.parents("form:first");
$form.submit();
}
};
$input.autocomplete(options);
};
var ajaxSubmit = function () {
var $form = $(this);
var settings = {
data: $(this).serialize(),
url: $(this).attr("action"),
type: $(this).attr("method")
};
$.ajax(settings).done(function (result) {
var $targetElement = $($form.data("ajax-target"));
var $newContent = $(result);
$($targetElement).replaceWith($newContent);
$newContent.effect("slide");
});
return false;
};
$("#search-filter").each(setupAutoComplete);
$("#search-form").submit(ajaxSubmit);
});
</script>
}
_PartialBooksList
#model IEnumerable<ImpressDev.Models.Book>
#using ImpressDev.Infrastructure
<div class="row">
#foreach (var book in Model)
{
<div class="col-12 col-xl-4">
<a class="o-shop-link" href="#Url.Action("Details", "Catalog", new { bookId = book.BookId })">
<div class="o-shop-item">
<img class="o-shop-img" src="#Url.BookPhotoSourcePath(book.PhotoSource)" />
<div class="o-shop-text">
<h2>#book.Title</h2>
<h6>#book.SubTitle - #book.Level - <b>#book.Price zł.</b></h6>
+ Add to cart
</div>
</div>
</a>
</div>
}
</div>
Please help
I am not sure if this is the case, but try to change this code:
$($targetElement).replaceWith($newContent);
To this:
$($targetElement).html($newContent);
I think the problem is the div element with id="booksList" is replaced after first search. So you don't have this element in the second search.
I looked through the code step by step and found a solution to my problem.
In the first search, replace id="booksList"
<div class="row" id="booksList">
#Html.Partial("_PartialBooksList")
</div>
partial view in which there was only without id = booksLists.
In the next search there was no ID in this place and there was nothing to replace.

How to get ID value using map()

I've page that contain the list button and search button.
index.php :
<li class="page-item" id="'.$i.','.$record_per_page.'"><a class="page-link" href="javascript:void(0);" >'.$i.'</a></li>
<input class="form-control" type="text" placeholder="insert your keyword ..." aria-label="Search" id="budget_keyword" name="<?=$record_per_page;?>">
script.js :
$(document).on('click','#table-content .page-item',function () {
var mode = this.id.split(',');
var page = mode[0];
var p = mode[1];
var keyword = $('#budget_keyword').map(function() {
return this.id.value;
});
$.ajax({
url: "paging.php",
method: "POST",
data: { page: page, p: p, keyword: keyword },
success: function (data) {
$('#table-content').html(data);
}
})
});
My Goals are :
When user click the li button, then it will pass 2 variables which containing values from #page-item and #budget_keyword id
I already got the value of #page-item from my script above, but for the #budget_keyword, it seems returning an object which i cannot understand below :
Object { length: 0, prevObject: Object(1) }
I just need the value from user input text inside searchbox (#budget_keyword)
Can someone give me an idea ?
sorry for my bad english
Seems like multiple inputs with same id="budget_keyword" exist in your HTML.Due to that keyword is not coming properly (or in other words to say map() not working).
You can use .next() to get desired keyword. Check below code:
$(document).on('click','#table-content .page-item',function () {
var mode = this.id.split(',');
var page = mode[0];
var p = mode[1];
var keyword = $(this).next('.form-control').val();
$.ajax({
url: "paging.php",
method: "POST",
data: { page: page, p: p, keyword: keyword },
success: function (data) {
$('#table-content').html(data);
}
})
});
Note:- if only one id="budget_keyword" exist in whole document,then directly do:
var keyword = $('#budget_keyword').val();

Implementing a Modal Factory?

I'be been using modals as a means to communicate to users in my apps for some time now via several different front end frameworks. The logic is usually the same, defining the modal's html then rendering it via some click event.
As my applications grow, so do the number of modals I use for a user prompt or confirmation - these modals can have anything from text inputs to forms to dropdowns and so on.
My current method is to write out each separate modal in a single html file and simply call them by their IDs but I feel this is inefficient as there is plenty of duplicate boilerplate code, so I'm wondering the best way would be to create modals dynamically while keeping the code as light andclean as possible?
I've been thinking of something like a "modal factory" where you pass the content of the modal along with the height, width, styling, etc. would this be a good approach?
Thanks for any input!
Well what I do for Forms/HTML Content loaded from the server - is create a div with an ID - PartialViewDialog at the end of my page -(I load Partial Views inside a Dialog)
This one is Bootstrap 3.* based - (HTML structure based on Frontend framework
So the HTML is like this:
<body>
<!-- Other page content -->
<div class="modal fade" id="PartialViewDialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" data-modal="title"></h4>
</div>
<div class="modal-body" data-modal="content">
</div>
<div class="modal-footer" data-modal="footer">
</div>
</div>
</div>
</div>
</body>
Then in JS, I create a dialog Manager:
var MyApp = MyApp || {};
MyApp.UIHelper = MyApp.UIHelper || {};
MyApp.UIHelper.DialogManager = (function () {
"use strict";
var self = {};
self.divId = null;
self.dialog = null;
self.dialogBody = null;
self.dialogTitle = null;
self.dialogFooter = null;
self.actionUrl = "";
self.modalObject = null;
self.options = {};
function Initilize(divId, options) {
self.options = $.extend({ buttons: [] }, options);
self.divId = divId;
self.dialog = $(self.divId);
self.dialogBody = self.dialog.find('*[data-modal="content"]');
self.dialogTitle = self.dialog.find('*[data-modal="title"]');
self.dialogFooter = self.dialog.find('*[data-modal="footer"]');
self.BootgridObject = null;
};
function OpenPartialViewDialog(url, title, preprocessingFunction, postProcessingFunction) {
// Create the buttons
var options = self.GetPartialViewButtons(url, preprocessingFunction, postProcessingFunction);
// Initialise the PartialViewDialog with Buttons
Initilize('#PartialViewDialog', options);
// Set the URL for Ajax content load and Form Post
self.actionUrl = url;
// Set Dialog Title
self.dialogTitle.html(title);
// Open the PartialViewDialog
self.OpenModel();
};
// This Method creates the buttons for the Form dialog
// e.g Save, Cancel, Ok buttons
self.GetPartialViewButtons = function (url, preprocessingFunction, postProcessingFunction) {
// I only need Save and Cancel buttons always so I create them here
var buttons = {
buttons: {
// I create a save button which Posts back the Form in the Dialog
Save: {
Text: "Save",
css: "btn btn-success",
click: function () {
// Call a function before sending the Ajax request to submit form
if (preprocessingFunction) { preprocessingFunction(); }
$.ajax({
type: "POST",
url: url,
// This Dialog has a Form - which is Post back to server
data: self.dialogBody.find("form").serialize(),
success: function (response) {
// TODO: Check if response is success -
// Apply your own logic here
if (response.hasOwnProperty("IsSuccess")) {
if (response.IsSuccess) {
self.dialogBody.html("");
self.dialog.modal("hide");
// TODO: Show Success Message
// You can call another function if you want
if (postProcessingFunction) {
postProcessingFunction();
}
} else {
// If failure show Error Message
}
}
},
error: function (response) {
// If failure show Error Message
}
});
}
},
Cancel: {
Text: "Cancel",
css: "btn btn-danger",
click: function () {
self.dialogBody.html("");
self.dialogFooter.html("");
self.dialogTitle.html("");
self.dialog.modal("hide");
}
}
}
};
return buttons;
};
// dynamic creating the button objects
self.CreateButtonsHtml = function () {
var htmlButtons = [];
$.each(self.options.buttons, function (name, props) {
var tempBtn = $("<button/>", {
text: props.Text,
id: "btn_" + props.Text,
"class": props.css + "",
click: props.click
}).attr({ "style": "margin-right: 5px;" });
htmlButtons.push(tempBtn);
});
return htmlButtons;
};
// This method will load the content/form from server and assign the modal body - it will assign the buttons to the Modal Footer and Open the Dialog for user
self.OpenModel = function () {
$.ajax({
url: self.actionUrl,
type: "GET",
success: function (response) {
// Handle response from server -
// I send JSON object if there is Error in loading the content - otherwise the result is HTML
if (response.hasOwnProperty("HasErrors")) {
// Means some error has occured loading the content - you will have to apply your own logic
} else {
//Server return HTML - assign to the modal body HTML
self.dialogBody.html(response);
self.modalObject = self.dialog.modal();
// show modal
self.modalObject.show();
}
}
});
// Create the buttons in the Dialog footer
var buttons = self.CreateButtonsHtml();
self.dialogFooter.html('');
for (var i = 0; i < buttons.length; i++) {
self.dialogFooter.append(buttons[i]);
}
};
return {
OpenPartialViewDialog: OpenPartialViewDialog,
};
})();
Then whenever I need to open a dialog from the server I can call it like this:
MyApp.UIHelper.DialogManager
.OpenPartialViewDialog('/Content/Load', "My Title",
function(){alert('pre-process')},
function(){alert('post-process')}
);
Note: The PreProcess + PostProcess are called when the Save button is clicked
Here is a working/demo example which shows what the above JS does - Hope it helps
In the demo I load Dummy HTML from a div id="dummycontent"
Fiddle: https://jsfiddle.net/1L0eLazf/
Button Fiddle: https://jsfiddle.net/1L0eLazf/1/

Categories