On my page I have a list of users. Each user has a profile page on an external site (not the same domain name). To save my client updating their profile details in 2 places, I am using PHP simple HTML Dom Parser. This gets the content of the users external profile page and returns it on my site.
What I am trying to do is load the users profile information into a div on my site only when the users name is clicked.
Each user looks like this:
<div class="actor_container" data-url="www.external-profile-url.com">
<img src="http://placehold.it/500x500" />
</div>
To get the contents of the external page I use this code:
$html = file_get_html('http://www.spotlight.com/5094-1276-6177');
echo $html->find('div.credits', 0);
Obviously this works at the minute as it is hard coded. However I need to make it dynamic so that the external profile info for each user is loaded when the relevant user is clicked.
Update from answer below:
I added this script to the top of the user list:
<script>
jQuery(function ($) {
$(".actor_container").load(function () {
return "http://79.170.44.105/samskirrow.com/nial/wp-content/plugins/nial-customizations/front-end/my.php?url=" + $(this).data("url");
});
});
</script>
then in my.php
<?php
$html = file_get_html($_GET["url"]);
echo $html->find('div.credits', 0);
Currently, when I click on a user, nothing happens
UPDATE
OK I've moved to using AJAX to access my.php. Here is what I have so far:
<script>
jQuery(document).ready(function ($) {
$('.nial_actor').on("click", function (e) {
e.preventDefault();
$.ajax({
url: "http://79.170.44.105/samskirrow.com/nial/wp-content/plugins/nial-customizations/front-end/my.php?url=" + $(this).data("url"),
type: 'GET',
success: function(res) {
var data = $.parseHTML(res);
// append all data
$('#all_data').append(data);
}
});
}); //on
}); // ready
</script>
However this returns the following error:
GET http://79.170.44.105/samskirrow.com/nial/wp-content/plugins/nial-customizations/front-end/my.php?url=undefined 500 (Internal Server Error)
So for some reason the url in data-url is not adding to the end of my ajax url. Have I missed something obvious?
Something like this works?
$(function () {
$(".actor_container").load(function () {
return "my.php?url=" + $(this).data("url");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="actor_container" data-url="www.external-profile-url.com">
<img src="...actor profile img..." />
</div>
And in the PHP file, you can add url as your GET param:
$html = file_get_html($_GET["url"]);
Note that there are lots of vulnerabilities in this methods. Keep this just as a guidance.
Related
I have a page that generates n links in a foreach loop:
...some html and php code
<?php foreach ($tables as $table):?>
... some elements generated ...
<td><a onclick="setPortalId(<?php echo $table['id']?>);$('#fileupload').trigger('click');" class="btn-success btn-sm"><i class="icon-plus white bigger-125"></i>Add / Change</a></td>
... another elements ...
<?php endforeach;?>
As you can see, the onclick event in each link execute 2 js functions,the first sets a js var with the php value $table['id'] because i will need this value to determine my zend route and the last function trigges the input fileUpload of the type file:
<input id="fileupload" type="file" class="hidden" multiple="" name="files[]">
and in the scripts i have this:
<script src="/js/vendor/jquery.ui.widget.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<script src="/js/jquery.iframe-transport.js"></script>
<!-- The basic File Upload plugin -->
<script src="/js/jquery.fileupload.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
var idPortal;
function setPortalId(valor) {
idPortal = valor;
}
/*jslint unparam: true */
/*global window, $ */
$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = '/precos/upload/id/'+ idPortal;
$('#fileupload').fileupload({
url: url,
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name + " adicionado").appendTo('#files');
window.alert(file.name + " Adicionado.");
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
</script>
My question is how I can get the idPortal of the clicked link in the last self-invoqued funtion?Any sugestions?
This is horrible design. You should try to keep your JS as unobtrusive as possible, ie. don't use event handler attributes like onclick. Attach the event handler via JS. There are times when this is impractical but I don't see any evidence that that is the case here.
What I would do on the PHP side is to add some classes and a data attribute that I can hook in to from JS:
<?php foreach ($tables as $table):?>
<td>
<a data-portal-id="<?php echo $table['id']?>" class="btn-success btn-sm btn-upload"><i class="icon-plus white bigger-125"></i>Add / Change</a>
</td>
<?php endforeach;?>
Now on the JS side I would simply read the data-portal-id from the clicked link, use it to set the URL on the file uploader, and then trigger the click to begin the upload workflow:
$(selectorForTheTable).on('click', 'a[data-portal-id].btn-upload', function (e) {
// pull the portalId from the link's data-portal-id attribute
var portalId = $(this).data('portalId'),
$uploader = $('#fileupload');
// set the url for the upload based on out portalId
$uploader.fileupload('option', 'url', '/precos/upload/id/'+ portalId);
// invoke the click
$('#fileupload').trigger('click');
});
The one thing missing here is that you might want to set something up so that when the uploader is closed or all the uploads complete the URL is set back to null or a URL of no consequence. This would help to ensure something going wrong on the client cant mistakenly upload files to the wrong endpoint.
Here is an example Fiddle that works as much as a Fiddle can :-)
You need to make your url global and update it later in that context. Use it like
var idPortal;
var url;
function setPortalId(valor) {
idPortal = valor;
url = '/precos/upload/id/'+ idPortal;
}
The easiest approach to seperate PHP (serverside business logic) and Javascript (non-business critical GUI enhencement), is to put all variables from PHP into the DOM and then later work with it:
<script>
var phpValues = <?php echo json_encode($yourPhpValuesArrayOrObject); ?>;
</script>
....
<script>
The attributes connected with business data from inside the HTML (=semantic structure) should go with a data-* attribute as already mentioned.
You're setting url when the page is first loaded, not after the user clicks on the link. Add that to the setPortalId function:
function setPortalId(valor) {
idPortal = valor;
url = '/precos/upload/id/'+ idPortal;
}
thank you everyone,but I used another approach to get the correct value of the clicked element.like was said,the function is self-invoked in the page loading,so in this moment the global var still null.I as using the blueimp jquery file upload,so reading the documentation I saw that is possible send another values during the ajax request just adding news inputs in the form.with this I solved my problem.
I am trying to send data to a index page when a link on that page is clicked. the index.php page looks like this:
include "../app/bootstrap.php";
include ("../src/controllers/DisplayContentsController.php");
$data = new DisplayContentsController();
$link = (isset($_POST['link']) ? $_POST['link'] : null);
if ($link != null)
{
$data->show($twig, $starting_file_path . '/' . $link);
$starting_file_path = $starting_file_path . '/' . $link;
}
else
{
$data->show($twig, $starting_file_path);
}
and on the Twig template that is loaded I have this:
<script>
jQuery('.show_content').click(function(e)
{
e.preventDefault();
var href = jQuery(this).attr('href');
jQuery.post(window.location, { link: href });
});
</script>
I want to reload the page with the new link that way it loads the correct directory. But when I do the jQuery.post() the content that is displayed does not change. Can someone help my find out what is going wrong and how I can accomplish this?
The output from the POST request would be returned on the success handler function. For example, you would need to do something like this:
jQuery('.show_content').click(function(e)
{
e.preventDefault();
var href = jQuery(this).attr('href');
jQuery.post(window.location, { link: href } , function(data){
//data will have the new HTML after the page posted back. You can use that
//HTML to load if onto an element on the page. Something like:
$('#content_result').html(data);
});
});
Assuming you have a div with "id = content_result" -or something like that- that you can use to load the HTML into it.
If you want to append the result to the existing HTML already displayed inside #content_result then simply do:
$('#content_result').html($('#content_result').html()+data);
Now, keep in mind that this will return everything - the full page - and if you blindly keep appending things, you'll end up with a page that does not conform to valid HTML -for example, a page with more than 1 <head>,<body> sections, etc. The best thing to do is to extract the section that you really care about, and append only that section such that you always end up with a valid HTML document.
jQuery offers plenty of options to do this sort of thing.
Is there a way to call a (jquery action/write an html text) to a div of a new page after calling the window.location command?
Im trying to make an ajax form submit where the user will be redirected to a new page upon submit,
and in that new page a hidden div will appear with text inside of it
currently this is my code
script.js
$.ajax({
url:url,
type:'POST',
data:datastr,
success:function(result){
if(result=="duplicate"){
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Duplicate Username</center></h4>");
$("#dept_name").closest(".control-group").attr('class', 'control-group');
$("#username").closest(".control-group").attr('class', 'control-group error');
$("#password").closest(".control-group").attr('class', 'control-group');
$("#username").focus();
}
else{
$("#dept_name").closest(".control-group").attr('class', 'control-group');
$("#username").closest(".control-group").attr('class', 'control-group');
$("#password").closest(".control-group").attr('class', 'control-group');
window.location = base + 'admin/departments/edit_dept/' + result;
}
}
});
i want to make this block of code below work on the page where window.location is going
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Successfully added Department</center></h4>");
is it possible?
thanks
You can use CI session flash data.
http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Before triggering window.location, set the message in flashdata. On the landing/redirected-to page, check to see if flashdata has a value (success/failure). If so, display (or trigger a js method to show) the message.
You could add a parameter with your window.location, like:
window.location = base + 'admin/departments/edit_dept/' + result + '?showMessage=12'
Then on the next page, have a jquery script that looks for that parameter and shows the message. See this question.
Or you can do it in on the server. But with jquery it works with static html too.
This is a patchup, May require some tuning though.
window.location = base + 'admin/departments/edit_dept/' + result+'/err'; //changed to catchup with the view part
In the Controller:
<?php
if($this->uri->segment(4) == "err"){
$data['err'] = true; #will reflect that we need to show the js in the view
$this->load->view('view', $data);
}
?>
In the view part:
<?php if(isset($err)){ ?>
<script type="text/javascript">
$("#status").attr('class', 'span12 alert alert-error');
$("#status").show();
$("#status").html("<h4><center>Successfully added Department</center></h4>");
</script>
<?php } ?>
I'm loading a custom page type that is just comments for a post. This is so I can use Disqus threads for easier usability when multiple loop posts are on a single page.
When loading an iFrame with the following structure I keep getting this syntax error. Are my escape characters wrong?
$(".boxyComments a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
$(".commentsIframeBig")
.get(0).contentWindow.location.href =
$("<?php echo get_site_url(); ?>","\/ajax-post-fold\/",post_id);
What's happening is the get retrieves the Wordpress hook to print the site url (in this case it prints http://whateverdomainex.com for the 1st call, 2nd should print /ajax-post-fold/ and the last call should print the post ID so the entire url ends up printing as http://whateverdomanex.com/ajax-post-fold/2825.
Instead my Chrome console gives me the following message:
Uncaught Error: Syntax error, unrecognized expression: /ajax-post-fold/
Update
I've put this variable into place and called it rather than the $("<?php echo get_site_url(); ?>","\/ajax-post-fold\/",post_id); as the get reference:
var postLink = $("<?php echo get_site_url(); ?>"+"\/ajax-post-fold\/"+post_id);
Implemented as such:
$(".boxyComments a").click(function (event) {
event.preventDefault();
var postLink = $("<?php echo get_site_url(); ?>"+"\/ajax-post-fold\/"+post_id);
var post_id = $(this).attr("rel");
$(".commentsIframeBig")
.get(0).contentWindow.location.href = postLink;
Which gives me the following Chrome message:
Uncaught Error: Syntax error, unrecognized expression: http://www.theciv.com/ajax-post-fold/28448
The URL that should be in the src attribute for the iFrame looks like it should be fine and good to go, so why is this syntax error still being output?
UPDATE
var postLink = "<?= site_url('\/ajax-post\/'); ?>"+post_id;
$(this).closest(".boxy").find(".commentsIframeBig")
.css("display","block")
.animate({height: "100%"}, 500)
.get(0).contentWindow.location.href = postLink;
With the proper structure above, the custom page is now loading in the iFrame. However the additional construct of +page_id which includes the rel attribute containing the post's id isn't loading properly.
Moreover when calling the new url as it's original custom page template, then adding the post's id does not load the correct page with post id. Confused yet? Read it again. Took me awhile to write that sentence.
In any case, now my mission to have the post id load when adding the custom page and the post_id as an added string for the iFrame's url to load properly.
update
Here is final working code to load Disqus comments into same page, pseudo multiple times.
Basically this is pushing a post id to the end of a custom page type, resulting in the post's content and attributable elements being loaded into the custom page template.
When stripping that custom page template down to just show the comments for the page, you can create a load/unload reaction whereby you are only calling Disqus once, removing that instance and then loading it again when another Load Comments button is clicked within a subsequently loaded post on the same page. Yay. Multiple Disqus commenting on one page with minimal Ajax loading.
Here is the structure et al that is almost working for me. Only 2 bugs left. First is the secondary load when emptying, then reloading the new Disqus page into the Ajax element using the .ajaxComplete() callback function.
What's happening now is the callback is basically not being fired at all. As far as I can tell. Clicking on it a second time however, does make the call. But this is due to the class parameters being met for the else statement.
Second bug left is I'm having a hard time figuring out how to get the appropriate elements to enlarge, while leaving the others the same size.
// Load comments and/or custom post content
$(".boxyComments a").click(function (event) {
event.preventDefault();
$.ajaxSetup({cache:false});
var post_id = $(this).attr("rel"); var excHeight = $(this).closest('.boxy').find('.initialPostLoad').height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb').height();
var postWidth = $(this).closest('.boxy').find('.articleImageThumb').width();
// close other comments boxes that may already be open
if($('.commentsOpen').length ) {
console.log('comments are open');
$('.bigBoxy').closest('.boxy')
.animate({height:(postHeight + excHeight)}, 500);
$('.showComments')
.removeClass('bigBoxy')
.removeClass('commentsOpen');
$('.commentsAjax')
.empty(function(){
$(this).closest(".boxy").find(".showComments")
.addClass("commentsOpen")
.addClass("bigBoxy");
$(".bigBoxy").find(".commentsAjax ")
.css("display","block")
.animate({height: "500px"}, 500)
.load("http://<?php echo $_SERVER[HTTP_HOST]; ?>/ajax-post/",{id:post_id});
$(this).closest(".boxy")
.ajaxComplete(function() {
var excHeight = $(this).closest('.boxy').find('.initialPostLoad')
.height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb')
.height();
$(this).closest(".boxy").animate({height: (postHeight + excHeight)}, 500)
});
});
} else {
$(this).closest(".boxyComments").find(".showComments")
.addClass("commentsOpen")
.addClass("bigBoxy");
$(this).closest(".boxy").find(".commentsAjax")
.css("display","block")
.animate({height: "500px"}, 500)
.load("http://<?php echo $_SERVER[HTTP_HOST]; ?>/ajax-post/",{id:post_id});
$(this).closest(".boxy")
.ajaxComplete(function() {
var excHeight = $(this).closest('.boxy').find('.initialPostLoad')
.height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb')
.height();
$(this).closest(".boxy").animate({height: (postHeight + excHeight)}, 500)
});
}
});
Okay, here's full working code to do what you want. You'll have to swap out a few placeholders for your actual code:
<script>
jQuery(document).ready(function($){$(".boxyComments a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
var postLink = "<?= site_url('/path/'); ?>"+post_id;
$("#myFrame").attr('src', postLink);
});
});
</script>
And sample divs & iFrame:
<div class='boxyComments'>
<a href='#' rel='some-url'>test link</a>
</div>
<div class=".commentsIframeBig">
<iframe id='myFrame' height="500px" width="800px" src=''>
</iframe>
</div>
Tested it locally and it worked no problem. You might have been running into issues with it not properly accessing the iFrame. If you can give the iFrame an id that makes it easier.
It's because you're declaring var postlink as a jQuery object. You just need to get it as a string that you can then pass to the iframe.
var post_id = $(this).attr("rel");
var postLink = "<?= site_url('/ajax-post-fold/'); ?>"+post_id;
UPDATE 2
Looks like the string shouldn't be included within the <?= get_site_url() ?> after all.
Instead I've created a few vars to affect it. Code updated below with answer:
var postDir = "\/ajax-post-fold\/";
var postLink = "<?= get_site_url(postDir); ?>"+"\/ajax-post-fold\/"+post_id;
This problem drive me nuts for two days.
I have strongly typed view with text area. User can write comment in that area. After button click I save comment and return view from action method with comment id and comment text. Returned view I add to div called "messages" and it works. Comments saved, View returned, Display fine but when I right click in browser for page source div "Messages" is empty.
This thing makes me problem. Each comment has edit button and if there is 5 comments in messages div when I click edit I got edit function called 5 times. But when I hard code HTML with comments in div messages it works. But when I ajaxify page nothing works as it should.
Here is the code:
<script>
$(function () {
$('#addMessageForm').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#messages').prepend($(result).fadeIn('slow'));
}
});
return false;
});
});
</script>
#using (Html.BeginForm("AddMessage", "Comment", FormMethod.Post, new { id = "addMessageForm" }))
{
#Html.TextAreaFor(a => a.CommentText);
<input type="submit" value="Submit Comment" />
}
<div id="messages">
</div>
This is add comment Action Method:
[HttpPost]
public ActionResult AddMessage(CommentModel model)
{
model.Author = "Vlada Vucetic";
Random r = new Random();
int n = r.Next(1, 1000000);
model.CommentId = n;
return View("CommentView", model);
}
This is what happen when I click edit button. But as I said when I add hard code comment div in div messages and click edit it called only once. I have no idea what is happen here? Why page source doesn't display anything in browser...
This is comment view. This is what I add to div messages.
#model Demo_AjaxPosting.Models.CommentModel
#{
Layout = null;
}
<script src="../../json2.js" type="text/javascript"></script>
<script>
$('.editButton').live('click', function (e) {
e.preventDefault();
var container = $(this).closest('div'); //$(this).closest('.commentWrap');
var itemId = container.attr('id');
alert(itemId);
var nestId = '#' + itemId;
var txt = $(nestId + ' #commentTextValue').text();
$(nestId + ' #commentTextValue').remove();
$(nestId + ' #editButton').remove();
$(nestId).prepend('<textarea id="editArea">' + txt + '</textarea>');
$(nestId).append('<input type="submit" value="Ok" class="btnOk" />');
})
</script>
<div style="border: 1px solid #dddddd;">
#Html.ActionLink(#Model.Author, "SomeAction") #Model.CommentId
<div class="commentWrap" id="#Model.CommentId">
<p id="commentTextValue">#Model.CommentText</p>
<a class="editButton" href="#">Edit</a>
</div>
</div>
The page source shows the page as it is initially received from the server. The DOM is created from the source and displayed. If you later add comments to the DOM (using jQuery), it will be displayed but the page source isn't updated. So far, that's expected behavior.
If you want to inspect the HTML after comments have been added, use a tool like Firebug. It works on the DOM and nicely handles dynamic parts.
The reason your event handler is executed several times is that you add it several times. Every time a comment is added, the Ajax answer transmits (and the browser executes) a script with the following line:
$('.editButton').live('click', function (e) {
As a result, you end up having several event handlers installed. They might have identical code. But that doesn't matter. They are installed several times. So if you click the "Edit" link, several of them are executed and you get several text boxes.
The solution is to move the Javascript code (including the SCRIPT tags) out of the CommentView and into the view of the main page.