How to stop execution of all js on page yii2? - javascript

Yii2. Example: (.../index.php)
<?php echo Html::a('Add new', ['/rode/prod', 'id'=>$model->id ], ['onClick' => '
var modal = $(".modal");
$.get("/rode/prod?id='.$model->id.'", function(data) {
modal.html(data).modal("show");
});
return false;'
]);?>
<?php echo Html::a('Add new', ['/rode/lok', 'id'=>$model->id ], ['onClick' => '
var modal = $(".modal");
$.get("/rode/lok?id='.$model->id.'", function(data) {
modal.html(data).modal("show");
});
return false;'
]);?>
And other...
When start to run a modal window on click button, all others run. How to do, to run only once, but not all ?

Use id in modals to identify them instead of class.
With unique id like i.e. newProd for the first model it will be:
var modal = $("#newProd");
For this to work you have to set id in modal's div like:
<div id="newProd" ...>
Add unique id to every modal like that.

Related

is there a way to update a div with new content only using ajax

This is the div that i am updating
but i want to add a active class to the (li) item
every time the div refreshes the active class goes away
so i don`t want to refresh all the data in the (ul) but
only add (li) if there is a new data in the database,
with out refreshing the previous (li) items
<div id="contacts">
<ul id="rooms" class="rooms">
<!-- This is where the data get inserted -->
<!-- the ajax call and this -->
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
</ul>
</div>
this is my ajax call
$(document).ready(function() {
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
success: function(data){
$('#rooms').html(data);
}
});
}, 1000);
});
in the room php
$rooms = get_rooms();
foreach($rooms as $room){
?>
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
<?php
}
the get_rooms() function
function get_rooms() {
$sql = "SELECT id, sender, senderemail FROM chatroom ";
$result = mysqli_query($GLOBALS['dbh'], $sql);
$rooms = array();
while($room = mysqli_fetch_assoc($result)){
$rooms[] = array('id'=>$room['id'], 'sender'=>$room['sender'],
'senderemail'=>$room['senderemail']);
}
return $rooms;
}
You Just need to push new data to the div as below just replace your line with:
$('#rooms').append(data);
this will add new <li> in your existing <div> after the last <li>
jquery append()
To get the id of the last <li>
var lastId = $( "#rooms li" ).last().attr('id');
Once you get the last id then pass it in your ajax call.
If I understand you correctly, your problem is that you lose the active class (which you clicked on the li container) when there is new data.
This has to do with the fact that you exchange all of the content.
There are now three options. Either
You give the rooms.php the id of the currently active li-container
and this script sets the active class for the affected container.
You transfer all the chatrooms (ids) already shown to rooms.php and only
load the new ones (this means effort later with sorting).
You save the active li class and re set it after content changed (this is the fastest)
f.e: in your Ajax succes functions:
let id=0;
let active_li = $('li.active');
if (active_li.length>0) id=active_li.data('val');
$('#rooms').html(data);
if (id!=0) $('li[data-val="'+id+'"]').addClass ('active');
A few other thoughts:
Note the interval of 1000ms. Possible it makes Problems if the request lasts longer than 1000ms. This may still work well in your tests, but maybe not anymore if there are a hundred or 1000 users in your application.
Doesn't it make sense to tell the server when you click the active room and save it in a session so that the server knows which room is active in the client?
You need to simply update your JS code like:
$(document).ready(function() {
var active_list = '';
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
beforeSend: function(){
active_list = $('#rooms').find('li.contact.active').attr('data-val');
}
success: function(data){
$('#rooms').html(data);
$(data).find('li[data-val="' + active_list +'"]').addClass('active');
}
});
}, 1000);
});
This should solve your problem and Let me know if you still face any issue.

yii2 assets missing when creating modal

I know there are a lot of similar questions I have tried all of them nothing working. In my modal there are assets missing, and I don't know how to, where to reload them.
EDIT: this is my start-form.php:
<?php $this->registerJsFile('js/voti.js'); ?>
<div class="box-footer">
<center><button id="ladeauswertung" class="btn btn-default">Auswertung Laden</button></center>
</div>
<div id ='auswertungdetail' name = 'auswertungdetail'>
<?= $auswertungdetail ?>
</div>
When the button "ladeauswertung" is clicked the followin JS code will be executed you can see here script-file.js:
$(document).on('click', '#ladeauswertung', function ()
{
var ausgewaehlterstandort = document.getElementById("standorte").value;
var datum = document.getElementById("datum").value;
$.get("index.php?r=voti/ladeauswertung&standort=" + ausgewaehlterstandort + "&datum=" + datum,
function (jsondata)
{
document.getElementById("auswertungdetail").innerHTML = jsondata;
}
);
});
and this code Part, which is in my controller:
$.get("index.php?r=voti/ladeauswertung&standort=" + ausgewaehlterstandort + "&datum=" + datum,
doing the following:
return $this->renderAjax('auswertungdetail', ["auswertung" => $auswertung, "gesamtauswertung" => $gesamtauswertung]);
so the modal appears after the button is clicked in my form, and in my modal there is a daterangepicker and a chart widget include. These widgets work great in every form BUT not in the modal, so I'm thinking that the assets are missing, but where do I load them?
Please help I'm searching since a couple of days.
Your HTML Code:
<div id ='auswertungdetail' name = 'auswertungdetail'>
</div>
Your Javascript Code:
<script>
$(document).on('click', '#ladeauswertung', function ()
{
var ausgewaehlterstandort = document.getElementById("standorte").value;
var datum = document.getElementById("datum").value;
$('#auswertungdetail').load("index.php?r=voti/ladeauswertung&standort="+ausgewaehlterstandort+"&datum="+datum").fadeIn("slow");
}
);
</script>
You just have to do coding in the controller as you are rendering the normal view.

How to work with custom shopping cart in php

I have successfully built a shopping cart and everything works fine.
Here is what i want to accomplish:
if a user clicks on the add to cart button, it should add to the cart and refreshe the same page with the added item update.
If a user clicks on the image or View button, it displays the image of the item.
my problem is as follows:
1. IF a user clicks on the add to cart button, it adds but redirects to the cart.php file (Which is not what i want, I want the page to reload with the added item update)
2. I tried using:
$head = $_SERVER['HTTP_REFERER'];
echo '<script>location.href="'.$head.'"</script>';
exit();
It seems to work well, when a user clicks add to cart button, but when a user clicks on image or click on view button, it refrehes the same page without allowing the user to view the image.
Below is my code.
//My custom shopping cart script
if (isset($_GET['pid'])) {
$pid = $_GET['pid'];
$wasFound = false;
$i = 0;
// If the cart session variable is not set or cart array is empty
if (!isset($_SESSION["cart_array"]) || count($_SESSION["cart_array"]) < 1) {
// RUN IF THE CART IS EMPTY OR NOT SET
$_SESSION["cart_array"] = array(0 => array("item_id" => $pid, "quantity" => 1));
} else {
// RUN IF THE CART HAS AT LEAST ONE ITEM IN IT
foreach ($_SESSION["cart_array"] as $each_item) {
$i++;
while (list($key, $value) = each($each_item)) {
if ($key == "item_id" && $value == $pid) {
// That item is in cart already so let's adjust its quantity using array_splice()
array_splice($_SESSION["cart_array"], $i-1, 1, array(array("item_id" => $pid, "quantity" => $each_item['quantity'] + 1)));
$wasFound = true;
} // close if condition
} // close while loop
} // close foreach loop
if ($wasFound == false) {
array_push($_SESSION["cart_array"], array("item_id" => $pid, "quantity" => 1));
}
}
$head = $_SERVER['HTTP_REFERER'];
//header("location: $head");
echo '<script>location.href="'.$head.'"</script>';
exit();
}?>
<!--My Products item Display-->
<div class="col-md-4">
<div class="product-img product-img-brd">
<img class="full-width img-responsive" src="../../backend/'.$product_img.'" alt="'.$product_name.'">
<a class="product-review" href="pro_single.php?pid='.$id.'">Quick review</a>
<a class="add-to-cart" href="cart.php?pid='.$id.'" ><i class="fa fa-shopping-cart"></i> Add to cart </a>
<div class="product-price">
<span class="title-price">$'.$price.'</span>
</div>
</div>
Instead of making it a link (with an anchor tag <a>), you'll want to write some JavaScript that will use one of the many different ways to call it with AJAX.
A simple version might look like this:
// update <a> in HTML
<a onclick="addToCart(' . $id . ')">Add to Cart</a>
// JavaScript
const addToCart = id => fetch('cart.php?pid=' + id).then(response => { /* do something with response here */ });
This is a simple version, but it gives you an idea. There are tons of guides for AJAX with all the different methods (I prefer the newer fetch(), but there is jQuery.ajax() and pure XMLHttpRequest too, amongst others).
When you use an anchor with a link, it's saying "go to this place", which isn't what you want. Using AJAX, you can pull down data without affecting the flow of the page itself.
Side note: ideally, change your <a> to a <button> as well. This will make it more semantic, since a button is a thing to click to do thing and an anchor is a link to another page.

Pass value of list view to ajax

I have a list that is being created dynamically. Part of code that creates a list is:
<ul>
<?
foreach ($folders as $folder)
{
$folder = str_replace("{imap.gmail.com:993/imap/ssl}", "", $folder);
$folder2 = str_replace("[Gmail]/", "", $folder);
?>
<li>
<a><div id="box"><? echo $folder2; ?> </div></a>
</li>
<?}
</ul>
<div id="maillist"></div>
o/p of $folder
GMAIL/All Mail
GMAIL/Drafts
GMAIL/Important
o/p of $folder2
All Mail
Drafts
Important
what i want is that when a user clicks on All Mail, value corresponding to it (in this case: GMAIL/All Mail) should get pass to another script through ajax. The same process should follow for the other values in list also
ajax code
<script>
$(document).ready(function(){
$('#box').change(function(){
var boxid = $('#box').val();
console.log($('#box'))
if(boxid != 0)
{
$.ajax({
type:'post',
url:'a_fetchmaillist.php',
data:{id:boxid},
cache:false,
success: function(returndata){
$('#maillist').html(returndata);
console.log(returndata)
}
});
}
})
})
</script>
Can anyone tell if its possible to do what i want and if yes then how will it be done
First of all do not assign the same id multiple times, instead, set a class (eg box).
Then assign a data attribute for the specific folder ( eg. box-allMails ) and select that attribute on change:
foreach ($folders as $folder)
{
$folder = str_replace("{imap.gmail.com:993/imap/ssl}", "", $folder);
$folder2 = str_replace("[Gmail]/", "", $folder);
?>
<li>
<div class="box" data-folder="<? echo $folder2 ?>"><? echo $folder2; ?></div>
</li>
<?}
Then on change:
$(document).on('click', '.box', function() {
var folder = $(this).attr('data-folder');
// ajax call..
});
UPDATE
Important: You have to listen to 'click' event instead of 'change' because you click on a div, not on an input (I've changed the code).
Event delegation: Take note at the code:
$(document).on('click', '.dynamic-element', function() { .. })
instead of:
$('.element').on('click', function() { .. });
The second will not work because you are creating the elements dynamically.
Clickable: You do not have to insert an anchor tag to make the list item clickable unless you want to redirect to another page. In your case, you can style the .box div in order to get a cursor-pointer like this:
CSS
.box { cursor:pointer }
jQuery will take care of the rest (Check the example)
$(document).on('click', '.box', function() {
var folder = $(this).attr('data-folder');
alert('You clicked on: ' + folder);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><div class="box" data-folder="folderOne">Folder One</div></li>
<li><div class="box" data-folder="folderTwo">Folder Two</div></li>
<li><div class="box" data-folder="folderThree">Folder Three</div></li>
<li><div class="box" data-folder="folderFour">Folder Four</div></li>
</ul>

How to open a modal-form, execute a action in the controller, and render the result in Grails

I have a table in my gsp where each row have a button to edit. This button open a modal panel with the form to edit this row.
When I open this modal, a js function run and make an ajax call to an action of the controller, passing the id of the row.
In the controller I search for the entity and then I return it to the view. But the problem is that in the view I can't see this object..
The code I have is:
GSP:
<a href="#modal-form" data-id="${cancha?.id}" role="button" class="open-EditCanchaModal btn btn-xs btn-info" data-toggle="modal" />
Then, this modal have a g:formRemote with 4 textFields inside to edit the properties
JS:
$(document).on("click", ".open-EditCanchaModal", function () {
var canchaId = $(this).data('id');
var newData = $.post("${createLink(controller: 'cancha', action: 'selectToEdit')}/"+canchaId);
alert("dat: "+newData); // it print dat: [object Object]
alert("can: "+newData.cancha); // it print undefined
});
GRAILS:
def selectToEdit = {
Cancha cancha = Cancha.get(params.id)
println cancha // this found the correct "Cancha"
[cancha:cancha]
}
So, I want to get the Cancha in the JS, after call the method selectToEdit, to render the atributes in the textFields of the modal panel.
I'm also new to Grails.
Correct me if I'm wrong.
Returned newData will be the string format of your object.
( not a real object, think it as the output of toString() )
So, to achieve what you are trying to do.
You may use JSON encode/decode to be the bridge between JS/GRAILS.
Creating a Grail Jquery Modal Window and Form posting with ajax?
some excerpt :
"Attach Comment": function() {
//do form posting here
$.ajax({
context: $(this),
url:"${resource()}"+"/issue/attachComment",
type:"POST",
data:{"comment":$('#commentArea').val(),"id":$("#selectedIssueInstanceId").val()},
success:function(data){
if(data.success)
{
var tobeAppendeID = $("#selectedIssueInstanceId").val();
$('#'+'comment_'+tobeAppendeID).val(data.newComment);
$( this ).dialog( "close" );
}
else
{
$('#error-message').addClass('ui-state-error ui-corner-all');
$("#error-message").html(data.message).show()
$(this).dialog("close");
}
$( this ).dialog( "close" );
}

Categories

Resources