I need help to show the data (from controller) in tooltip (using qTip script) on MouseOVer event.
User mouserover on link (Multiple links like in foreach)
id send to a js function like function getData(id){}
Call the PHP function from the controller & using the variable return the data to tooltip.
Show return data into tooltip.
HTML & PHP:
foreach ($rows as $row) {
<a href="#" onmouseover="getData(<?php echo $row->id; ?>)" >Name</a>
}
JS function :
function getData(id)
{
var url='index.php?option=com_test&controller=test&task=getDetails&format=raw';
var data = 'item_id=' + id ;
var request = new Request({
url: url,
method:'post',
data: data,
async: true,
onSuccess: function(responseText)
{
// How i show the "responseText" data here in tooltip using qTip
}
}).send();
}
Controller function:
function getDetails()
{
echo $return = JRequest::getVar('item_id');
}
Would it not be easier to preload the tip in a content item view override (add it to the title= attribute), and adding the call to qTip (one per page) would do the trick.
Also, ajax would make the tooltip not very quick.
Just make sure you properly escape " or ' characters in the title attribute or you will break your markup.
edit: added code. i'm writing this here so there may be typos, but it should give you the idea:
foreach ($rows as $row) {
// let's assume $tip contains the right tip for each row:
Name
}
This first part will show the default browser tooltip.
Now you have to inject the qTip script:
$document = JFactory::getDocument();
$document->addScriptDeclaration('
jQuery("a.tipme").qTip();
');
Now how to put the value in $tip? I see you have a com_test component, you don't need to go through the controller, but can instantiate directly the model that will provide the tooltip; if it's called "tip":
$tipmodel=JModel::getInstance('tip', 'ComtestModel'); // get the model (once!)
$tip = $tipmodel->getTip($row->id);
All the variable, model, controller names in this story are fictional.
Related
I have an anchor tag and would like its data-id to be sent to a function in the controller which would in turn retrieved data from the database through the model.
However the data is not getting past the controller. The ajax response is showing that the data was sent but controller shows otherwise.
Here is my ajax code:
$(document).on("click",".learn-more",function(){
var sub_item_id = $(this).data("id");
$.ajax({
url:"<?php echo base_url();?>Designs/business_cards",
type:"POST",
data:{sub_item_id:sub_item_id},
success:function(data){
console.log(data);
},
error: function(error){
throw new Error('Did not work');
}
})
});
I had set datatype:"json" but the data was not being sent so I removed the datatype and it worked,the ajax part that is.Or atleast the response showed that data was sent.
My controller code is:
function business_cards(){
$id = $this->input->post('sub_item_id');
$data['quantity'] = $this->subproduct_model->get_quantities($id);
$this->load->view('category/business-cards',$data);
}
My model code is:
public function get_quantities($sub_item_id){
$this->db->select('quantities');
$this->db->where('id',$sub_item_id);
$query = $this->db->get('sub_products');
return $query->result_array();
}
HTML Code which includes the anchor tag
<?php foreach ($results as $object):?>
View Prices
<?php endforeach?>
The data-id is displaying the correct value as per the iteration.
When I check the result array of the model code it is an empty array showing that the $sub_item_id was not passed in the controller. What could be the problem?
I just copied your code and I was able to get the value in the controller.
In your controller function do var_dump($id). Then in your developer tools (F12) check the console. Since you have console.log(data) that var_dump should be in the console. It won't show on the screen.
Some other things to check:
Does your db have records with that ID? Could your db result array be empty because it actually should be?
Are you sure that the data-id actually has a value when you click the tag?
it is not passed to the controller because you forgot to put a parameter inside the function of your controller.
Note: you cannot use input post because you're not using form.
function business_cards($id){ //put a parameter here, serve as container of your passed variable from **ajax**
//$id = $this->input->post('sub_item_id');
$data['quantity'] = $this->subproduct_model->get_quantities($id); //pass the id to your model
$this->load->view('category/business-cards',$data);
}
change your ajax code to this..
$(document).on("click",".learn-more",function(){
var sub_item_id = $(this).data("id");
$.ajax({
url:"<?php echo base_url('Designs/business_cards/"+sub_item_id+"');?>", //pass the id here
type:"POST",
success:function(data){
console.log(data);
},
error: function(error){
throw new Error('Did not work');
}
})
});
In my application I have a form in controller/index that consists out of 3 select boxes. When all three boxes have a value selected I need to show additional html and extra form options in the same view based on those select values. The obvious solution seems to make an ajax call to another action that handles the database operation and creates a view and loading that view into the controller/index.phtml
I have been able to load a view of another action in the index.phtml by using:
$('#select').change(function() {
event.preventDefault();
var id = $(this).attr('id');
$('#results').show();
$('#results').load('/controller/index/' + $(this).attr('value'));
return false;
});
However I need to pass the variables of all three select boxes and for that I alternatively used:
$('#select1').change(function() {
var select1 = $('#select1').val();
var select2 = $('#select2').val();
var select3 = $('#select3').val();
$.ajax({
type: 'POST',
dataType: 'json',
url: '/controller/index/',
data: { select1: select1, select2: select2, select3: select3},
success: function(result){
var return1 = result.return1;
var return2 = result.return2;
}
});
});
The last method works in as far that I do see the variables passed in the headers and the response contains the view, but I cant fix it that just the content of the ajax view is placed within the index view. (Ofcourse by not using AjaxContent switching, the ajax view will load but that includes the complete layout as well.) Anything that I echo in the ajax action or ajax view do not show in the index view. Any pointer would be more than welcome
EDIT
the ajax action now looks like
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$select1 = $this->_request->getParam('select1');
$select2 = $this->_request->getParam('select2');
$select3 = $this->_request->getParam('select3');
// DO THE OTHER STUFF AND LOGIC HERE
$results = array(
'return1' => 'value1',
'return2' => 'value2'
);
$this->_response->setBody(json_encode($results));
and the controller init
public function init() {
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('ajax', 'json')->initContext();
}
So everything works, I can see the returned values in the response by using developer tool (network) in my browser, however I just do not know how I can use this to "update" the view
You can do two things:
You can enable the layout of the action you are calling via ajax. See you have disabled layout so even if the view phtml file of the ajax action contains something, it won't show. You can enable layout, use text/html dataType instead of json and show the returned HTML somewhere.
Or, in the success event of the ajax call, write javascript codes to update DOM.
Thanks #Salman for your suggestions as they lead me in the right direction and I managed to solve the problem.
I managed to pass multiple parameters with the ajax .load() call by passing them as get parameters.
The results of the ajaxAction could then be formatted in the ajax.ajax.phtml view and were consecutively
shown within the #results div that resides in the index.phtml where the select boxes are.
controller/index.phtml
<div id="results" style="display:block;">Select all three values</div>
IndexController init and ajaxAction
public function init() {
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('ajax', 'html')->initContext('html');
}
public function ajaxAction() {
$select1 = $this->_request->getQuery('select1');
$select2 = $this->_request->getQuery('select2');
$select3 = $this->_request->getQuery('select3');
$form = new Application_Form();
// Database operations and logic
$this->view->form = $form;
$this->view->array = $somearray;
}
}
jquery script in index.phtml
$(document).ready(function(){
$('.selector').change(function() {
var select1 = $('#select1').val();
var select2 = $('#select2').val();
var select3 = $('#select3').val();
if ( select1 && select2 && select3) {
$('#results').show();
$('#results').load('/controller/ajax?select1=' + select1 + '&select2=' + select2 + '&select3=' + select3);
}
});
});
controller/ajax.ajax.phtml
<?php if ( $this->array ) : ?>
<?php echo( $this->form ); ?>
<?php else: ?>
Nothing found for selected values
<?php endif ?>
Can anyone help me with, I am trying to create a download counter to my website.
I have a ajax script that counts up by 1 when the users clicks the download link, the issue I am having is on some browsers it goes to the download link before completing the ajax count script.
Is there a way that I can redirect to the download file once the script has completed. At the moment I have as follows
This is the link :-
<a href='downloads/".$downfile."' onclick=\"Counter('$referid');\"'>Download File</a>
This is the counter script:-
<script type="text/javascript">
function Counter(id)
{
$.get("clickcounter.php?id="+id);
{
return false;
}
}
</script>
This is the php script (clickcounter.php)
<?php
include('dbutils.php');
$referid = $_GET['id'];
$q = "SELECT * FROM downloads WHERE downid =".$referid;
$r = mysql_query($q);
while ($row = mysql_fetch_array($r))
{
$click = stripslashes(trim($row['downcount']));
$download = $row['downfile'];
}
$countup = $click + 1;
$qUpdate = "UPDATE downloads
SET downcount=$countup
WHERE downid=$referid";
$rUpdate = mysql_query($qUpdate);
?>
A few relatively small modifications should solve the problem. First, change the onclick to the following:
onclick=\"Counter('$referid', this); return false;\"
What we have done is to send in this as the second argument to the Counter function so we have a reference to the clicked link. Secondly, we have added return false, which blocks the browser from navigating to the url specified in the href.
The modified counter function looks like this:
function Counter(id, link) {
$.get("clickcounter.php?id=" + id, function() {
location.href = $(link).attr("href");
});
}
We now have a reference to the clicked link. A function has now been specified as the second argument to $.get(). This is the success-function, which is called when the ajax call has been successfully called. Inside that function we now redirect to the url specified in the href attribute on the clicked link.
I feel I should point out that the recommended way is to bind the onclick using jQuery separate from the html. The referid can be stored in a data attribute (which I chose to call data-rid):
<a href='downloads/".$downfile."' class='dl' data-rid='$referid'>Download File</a>
Then you bind the onclick for all download links (a elements with a "dl" class):
$(function() {
$("a.dl").click(function() {
var id = $(this).attr("data-rid");
var href = $(this).attr("href");
$.get("clickcounter.php?id=" + id, function() {
location.href = href;
});
return false;
});
});
(I feel I should point out that the code has not been tested, so it's possible that a typo has snuck in somewhere)
Using node.js and express (2.5.9) with express-form.
How should I repopulate form fields with the submitted values?
I have a get and a post route. If there are validation errors when the form is posted, I redirect the user back to the get, the problem is that the repopulated locals don't show up (I do have autoLocals: true, so I assume it's because I am redirecting and res is reset.)
So how do you guys repopulate and what's your application flow, do you res.send instead of res.redirect and set up the whole thing again? That seems repetitive.
Here's an example of my post route:
app.post(
'/projects/:id'
, form(field("title").required("title", "Title is required)
, function (req, res){
if (!req.form.isValid){
res.redirect('/project/'+req.params.id+'/edit');
}
else{
// save to db
}
});
I am working with expressjs4.0 to repopulate the forms fields after validation you do:
router.route('/posts/new')
.get(function(req, res) {
res.render('posts/new', new Post({}));
});
The second argument in res.render below will set some variables in the view.
res.render('posts/new', new Post({}));
In my view I then set my form fields as follows:
...
<input type="text" name="title" value="<%- post.title %>">
<textarea name="article"><%- post.article %></textarea>
...
When you submit this form, it should be caught by your router like so:
router.route('/posts')
.post(function(req, res) {
var post = new Post(req.body)
post.save(function(err) {
if (err) {
res.locals.errors = err.errors;
res.locals.post = post;
return res.render('posts/new');
}
return res.redirect('/posts');
});
...
})
This line of code, resets the form fields in your view
res.locals.post = post;
I hope someone finds this useful ;)
Not sure if it's best practice, but when I have validation failure, I don't redirect I just re-render the view (often by passing control to the 'get' callback). Somethign like this:
function loadProject(req,res, id){ /* fetch or create logic, storing as req.model or req.project */}
function editProject(req,res){ /* render logic */ }
function saveProject(req,res){
if(!req.form.isValid){
editProject(req,res);
}else{
saveToDb(req.project);
res.redirect('/project'+req.project.id+'/edit');
}
}
app.param('id', loadProject);
app.get('/projects/:id/edit', editProject);
app.post('/projects/:id', saveProject);
I had to work on similar problem recently and used two node modules: validator and flashify.
In the form view I configured my form fields as follows:
div.control-group
label.control-label Description
div.controls
textarea(name='eventForm[desc]', id='desc', rows='3').input-xxlarge= eventForm.desc
div.control-group
label.control-label Tag
div.controls
select(id='tag', name='eventForm[tag]')
tags = ['Medjugorje', 'Kibeho', 'Lourdes', 'Fatima']
for tag in tags
option(selected=eventForm.tag == tag)= tag
Notice the naming convention of the form fields. Then in my config file I set one global variable, which is really just a placeholder for when the form first loads:
//locals
app.locals.eventForm = []; // placeholder for event form repopulation
The validation logic is in my router file and looks like this:
app.post('/posts', function(req, res){
var formData = req.body.eventForm;
var Post = models.events;
var post = new Post();
post.text = formData.desc;
post.tag = formData.tag;
// run validations before saving
var v = new Validator();
var isPostValid = true;
// custom error catcher for validator, which uses flashify
v.error = function(msg) {
res.flash('error', msg);
isPostValid = false;
}
v.check(post.text, "Description field cannot be empty").notEmpty();
v.check(post.tag, "Tag field cannot be empty").notEmpty();
Then I check to see there are errors, and if so, pass the form data back to the view:
// reject it
res.render('Event.jade', {page: req.session.page, eventForm: formData});
Notice this evenForm data gets passed back to the view, which repopulates the default values.
The final step is to include the flashify component in your form view.
div(style='margin-top: 60px').container-fluid
include flashify
The code for the flashify view looks like this:
if (flash.error != undefined)
div.container
div.alert.alert-error
b Oops!
button(type='button', data-dismiss='alert').close ×
ul
each error in flash.error
li= error
if (flash.success != undefined)
div.container
div.alert.alert-success
b Success!
button(type='button', data-dismiss='alert').close ×
ul
each success in flash.success
li= success
I am using Codeigntier and I have the following dropdown in my view file which populates a list of subjects.
<?php echo form_dropdown('subject1', $dropdown_subjects,'',
'class="required" id="subject1"'); ?>
Now when any one selects any value from the dropdown above, I want to send the value to my controller using jquery and query in the following table( SELECT teacherid from table3 WHERE subjectid=$subjectid) to get the teacherid so that I can populate the teacherid list in another dropdown select. If any user changes his selection from the first dropdown I want to get the values of the second dropdown changed also
Table Name: table3
subjectid teacherid
1 1001
2 1003
So the bottom line is I want to populate a dropdown based on another dropdown. I have found couple of tutorials on this topic but I couldn't really understand those(I know I am stupid).
Would you please kindly show me how my view and controller should look like if I want to achieve this?
Thanks :)
EDit
Hi, this is how my controller and view file looks like :
My Controller
$id= $this->input->post('subject_id'); //receiving the ajax post from view
$this->db->select('teachername,teacherid');
$this->db->from('subject_teacher');
$this->db->join('teacher', 'teacher.teacherid = subject_teacher.teacherid');
$this->db->where('subjectid',$id);
$records = $this->db->get('');
$data=array();
$data[''] = 'Select';
foreach ($records->result() as $row)
{
$data[$row->teacherid] = $row->teachername;
}
return ($data); // I need help here... How to send the data as json?
My view:
<script>
$(function(){
$("#subject").change(function(){
$.ajax({
url: "<?echo base_url();?>mycontroller/function",
data: {subject_id: $(this).val()},
type: "post",
success: function(msg){
$("#teacher").html(); // I need help here...how do I get the value from controller and append to my another dropdown named teacher?
})
})
}); // function ends here
</script>
<?php echo form_dropdown('subject1', $dropdown_subjects,'',
'class="required" id="subject1"'); ?>
<select name="teacher" id="teacher">
<option value="">Select</option>
</select>
Please make the necessary changes in my View and Controller for me.
Thanks in Advance :)
You can do this by using jquery ajax. First you post subject_id to ajax page, ajax page will return the list of teacher in combo box and then the result is populated in the first page.
$("#subject").change(function(){
$.ajax({
url: "your-ajax-page-url",
data: {subject_id: $(this).val()},
type: "post",
success: function(msg){
$("#teacher").html();
})
})
This is the edited controller
$id= $this->input->post('subject_id'); //receiving the ajax post from view
$this->db->select('teachername,teacherid');
$this->db->from('subject_teacher');
$this->db->join('teacher', 'teacher.teacherid = subject_teacher.teacherid');
$this->db->where('subjectid',$id);
$records = $this->db->get('');
$output = null;
foreach ($records->result() as $row)
{
$output .= "<option value='".$row->teacherid."'>".$row->teachername."</option>";
}
echo $output; // HTML example
you may do it like this :
you will have to create a function inside your controller which will populate the data but instead of outputting your view you will have to put it inside a var like this
$outout = $this->load->view('myselect_output',$data,TRUE);
and then in your main view you will have to manipulate the DOM with jquery or any other js library ..