I don't consider myself a professional by any means. I decided to spend this summer picking up a few web languages that would allow me to prototype my ideas (I am a designer).
To get with the question, I am having a tough time figuring out how to manipulate elements that I am echoing back from an external .php script. Essentially I am doing this.
process_feed.php:
- Gets data, does SQL search based on data, outputs rows
while ($row = mysql_fetch_assoc($feedResult))
{
$ctime = date("U",strtotime($row['timestamp']));
echo '<div id="secretmsg">'.$row['secretmsg'].'</br>';
echo '<div id="postedby">Posted By: '.$row['postedby'].'</div>';
echo '<div id="timestamp">'.ago($ctime).'</div><button type ="button" name="'.$row['m_id'].'">Reply</button></div>';
}
main page:
function RefreshFeed()
{
var SchoolName = document.getElementById('schoolname').innerHTML;
$.post('../../process_feed.php', {name: SchoolName}, processResponse);
function processResponse(data) {
$('.secretfeed').html(data);
}
}
Perhaps not the best solution, but I have RefreshFeed on an interval so I can constantly get updated information.
The issue is this: I am trying to work on a comment system where users can respond to each post. On my process page, I am adding a Reply button with the name set to the ID in the database. I am trying to setup basic functionality where the Reply button will open up a text input for commenting, send the message to the DB based on the ID, etc etc. However, on my main page I am not able to manipulate the element because it's being echoed? What can I change in order to echo information from the database onto my main page, and then from my main page manipulate the echoed div's.
I hope this makes sense - thanks for the help :)
If I understand you correctly then you would like to modify the DOM once the data has been added - so you can then just use a selector to get the desired element and do what ever you want - e.g.:
function processResponse(data) {
// Selector to get all elements by class name within the whole document
$('.secretfeed').html(data);
// Selector to get all buttons by tag name inside $('.secretfeed')
$('.secretfeed').find('button').text('foo');
// Selector to get all buttons by attribute inside $('.secretfeed')
$('.secretfeed').find('[type="button"]').text('bar');
// Selector to get the element with the given id within the whole document
$('#secretmsg').css('color', '#ff0000');
}
Notes:
Ids for HTML elements should always be unique within the whole document! In your example you possibly echo multiple elements with the same id (as it is inside a while loop) - use class="" instead.
It is recommended to save selectors so that jQuery does not need to parse the DOM over and over again - e.g.:
var $myselector = $('.myclass');
$myselector.text('foo');
But keep in mind that the selector is not updated when you modify the DOM by e.g. adding another element with class="myclass" - you would then need to assign the variable again so the selector contains the newly inserted element as well.
Additionally be sure that the DOM is ready when you want to work on it - regarding your callback processResponse this will always be the case as jQuery takes care of it and does not execute the callback until it is ready - but when you come from a page reload wrap your code like this:
var $myselector = $();
$(document).ready(function(){
$myselector = $('.myclass');
});
Additional info:
Finally (out of the scope of your question) take a look at event delegation so that you do not need to select all elements directly - e.g. if you want to add a click handler to all of your buttons you do not need to register an event handler for each but can create a global one:
$(document).on('click', '.secretfeed button', function(){
alert($(this).attr('name'));
});
Related
I am receiving an XML data form result and using the Strophe library to convert it into html.
This gives me a chunk of HTML (form) as a variable, which I can then append to a page:
var iqHtml = iqForm.toHTML();
$("#form-result-div").append(iqHtml);
The issue is that the form which it attaches has no id, action, or anything to identify it:
<form data-type="result">
...
I have two possibilities here.
Option 1. (preferred method)
Is it possible to change the variable iqHtml, which is just raw HTML, and an ID to it? Ideally this would be done before it is appended to the page.
I've tried multiple ways to find the form tag and add the attribute using .find() and .attr() but with no success.
Option 2. (less preferable)
I can edit the library to add a random ID (say id="some-id") which I will then need to EDIT rather than creating new.
This editing will have the questions as Option 1 - how do I search the variable and then change the form's ID.
Thank you.
Kind Regards,
Gary Shergill
You could assign an id before appending it
$(iqHtml).attr('id', 'someid').appendTo("#form-result-div");
Edited: id needs to be in ''
This should work:
var iqHtml = "<form><input type='text' /></form>";
$("#form-result-div").append(iqHtml).find("form").attr("id", "myForm");
Demo: http://jsfiddle.net/AA8Cf/
You can also play with one of the child selectors to pick up a specific one, if there is more than one form.
http://api.jquery.com/category/selectors/child-filter-selectors/
I am beginner in jQuery and asp.net. I created a simple chat application using SignalR, the design of which you can find here fiddle
How can I create a new instance of that chat design whenever a user has been call by other user while he/she were in chat from before with other user. Here I think I can convert it to User Control. but I dont want to have same Id's which I am using for other chat design and those generated instances should work differently, I mean if userA calls userB and at the same time userC calls userB then they must be created in such a way that they must be unique in handling there own calls (just like FB Chat).
The another issue may arise after successfully creating a new instance is that they might not be get attached to the jQuery functions and server side code automatically. If so, anyway to solve this too?
Before asking here I searched alot (maybe I dont know the exact keyword to search for).
EDIT: Many jQuery developers suggested me to go with Knockout.js or Backbone.js or simple jQuery. But I think there is some simple way to achieve this using ASP.NET functions like User Control or HTTP Handlers (or something else). About which I dont know anything. So, please suggest me which concept to opt for ? and please give detailed explanation(if possible with simple example).
jquery related answers are also welcome.
Single Instance
Multiple Instances
Use JQuery to populate or popup new instance of chat but change your ids using jquery. I would suggest have all your styling and ids done according to a parent container so you can easily grap the parent, duplicate it and change the IDs or content.
I would keep a non filled chat window with ID's like "updateme1" updateme2 etc and then once i get it as a template i will replace all ids one by one with relevant content.
You are doing it right and i dont think its signalR that you need to look into. SignalR would be able to help you pass on specific parameters like "requirechatwindow=true or false" based on if this person is in chat with current person but you can always do this on client as well by going through current open chat sessions. If current chat session does not contain a chat between A and B then open new window with new ID and put a data-from= A and data-to=B as a palceholder so you know this chat is between A and B etc
Hope this helps
UPDATED Fiddle and technique
Here is the fix on Your fiddle edited to show creation and multiple ids I had to adjust some of your css to view the boxes in different location
Updated the code with some comments
The technique is simple:
You create a html template on your page might be in a hidden region
You then use that to create new element in a container and have a handle to pickup this element for example in my code the currentid is my handle but i know the container name so i will only pickup template populated within the actual container to avoid conflict with template itself.
Assign a new id and then you can use any events or any speacial objects on there.
You can then pickup new elements from the new id or any other handle you might have inside them. For example i have just added a click even on it with confirm to hide it.
$('#doubleme').click(function(){
var currentid = $("#chattemplate .chat-outline").attr('data-tid');
var newid = parseInt(currentid,10) + 1;
$("#chatcontainers").append($("#chattemplate").html());
$("#chatcontainers .chat-outline").attr('id',"id"+newid);
$("#chattemplate .chat-outline").attr('data-tid',newid);
});
You only need these five lines of code actually and if you go to fiddle i have commented all of them but they are easy to understand. I am using selectors used in fiddle but these can be further optimised with attributes like data-handle-for or whatever name you can give.
If you are considering this for SignalR then within your hub response of new request you can call the intiate chat window which can setup everything on the client. Any subsequent messages using that data handle can be updated within this new chat window.
For example i assume you create a new group called "chatwindow7" and "chatwindow8" which makes its round trip in your send method and so on get broadcast to only user with this group. Then each user might have multiple windows open but you only need to pickup chatwindow7 for messages with that data handle and update it and so on.
If you are using one-to-one chat users only then you can use connection id as well which means all messages broadcasted will have both sender and reciever (by deafault) connection ID and you only need to pickup the window with connection id handle and update its list of messages or whatever.
The simplest way to do this is to replace the id attributes with class attributes.
<div id="chat-outline">
...
</div>
becomes
<div class="chat-outline">
...
</div>
And update your CSS appropriately.
.chat-outline
{
background-color: gray;
....
}
Then use a text/template tag to make it available to jQuery.
<script type="text/template" id="chat-template">
<div class="chat-outline">
...
</div>
</script>
Note that because browsers ignore script types they don't recognise, this will be ignored by the html rendering engine, but as it has an id, it will be visible to jQuery, and can be accessed thus:
<div id="container">
</div>
<script type="text/javascript">
$(function() {
var chatTemplate = $('#chat-template').html();
$('#container').append(chatTemplate); // First instance
$('#container').append(chatTemplate); // Second instance
$('#container').append(chatTemplate); // Third instance
});
</script>
Of course, if your code needs an id attribute as a handle for a chat instance, you can create a function that creates the chat-instance html given an id. In this case I'll use underscore to provide random-id, template, and iteration functions, but it is easy to use another library, or write your own.
<div id="container">
</div>
<script type="text/template" id="chat-template">
<div class="chat-outline" id="<%= id %>">
...
</div>
</script>
<script type="text/javascript">
var createChatInstance(idstring) {
return _.template($('#chat-template').html(), { id: idstring });
}
$(function() {
var chatTemplate = $('#chat-template').html();
// Create an array of 3 unique ids by which chat instances will be accessed.
var chatIds = [_.uniqueId('chat-outline'),
_.uniqueId('chat-outline'),
_.uniqueId('chat-outline')];
_.each(chatIds, function(chatId) {
$('#container').append(createChatInstance(chatId));
});
// You now have an array of 3 unique ids matching 3 divs.
// You can access individual sub-divs via descendent class matching from the id
// thus: $('#' + chatIds[n] + ' .chat-message').keyup(...code handling event...);
});
</script>
At this point, if you want to take the architecture further, you really do need to consider investigating something like backbone.js.
Hope this helps.
I have been trying many times to write a code using JavaScript events,
so I thought that JavaScript's document.write will be somehow similar to
PHP's echo.
Is there any way to force document.write to perform an inline write similar to PHP's echo?
The sample: Situation
My website
<input type="text" id="inputText" onchange="writeText()">
Script
<script>
function writeText(){document.write(document.getElementById("inputText").value);}
</script>
I want it to act like every time you change the value of the text box, it will display the value of the textbox just below the text box where it came from or much nicer have it executed by using PHP's echo with some how like this:
<script>
var inputs = document.getElementById("inputText").value;
function writeText(){document.write("<"."?php "."echo '".inputs."';"."?".">");}
</script>
Note: please don't use elements to catch the values, I know it but what I want to aim here is to write inline with document.write without deleting the other contents of the page.
document.write() is not designed for use from event handlers because if the current document has already finished loading (which it has when an event fires), then document.write() first clears the current document and then adds new content to the empty document.
To add content to a document after it has already loaded, you need to either modify the innerHTML of an existing element or create new elements and programmatically add them to the page.
In your question, it is not clear where you want the writeText() function to put the content that it generates, but here's an example of append some new content into a document at a particular location in the document.
function writeText(parentElem, newHTML) {
var elem = document.createElement("span");
elem.innerHTML = newHTML;
parentElem.appendChild(elem);
}
I'm working with on developing one of the social networking site and its having some notification features in left panel.
Whenever any user have played a game it will automatically change the number of notification count.
For that i have using below code line.
jQuery('#count_id').load('mypage.php');
But it will retrieve me whole site content with header,footer and content area in the response text, which is wrong as per my requirements.
but if i used below code of line
jQuery('#count_id').load('mypage.php #count_id');
then it will retrieve me a real count but add another div in between the original,
Original html:
<div id="count_id" class="notify">2</div>
and Code after retrieving response:
<div id="count_id" class="notify">
<div id="count_id" class="notify">1</div>
</div>
which is also not as expected. count are right but i don't want to add new div inside a original one.
What should i need to change in my code?
Thanks.
jQuery('#count_id').load('mypage.php #count_id > *');
That would bring only the DOM childs (the content)
Because this is how it works. Also it enables you to attach events to the element you load and delegate them inside this element (so new elements can also benefit from attached JavaScript events) - see .delegate().
If you want to replace the element, you can try the following:
jQuery.get('mypage.php', function(data){
jQuery('#count_id').replace(jQuery(data).find('#count_id'));
}, 'html');
I did not test it, but it should work.
Ivan Castellanos is however right. According to the documentation, you can provide any selector after the first space in the .load()'s parameter.
To retrieve count_id, you can directly get the html value in the div like this:
<script type='text/javascript'>
jQuery(document).ready(function()
{
countVal = $("#count_id").html(); //returns the html content inside the div, which is the count value
countVal = parseInt(countVal); //This will convert the string to type integer
});
</script>
Note:
If you want increase the count and update the div value, you can add the following lines:
countVal++;
$("#count_id").html(countVal);
I'm creating a simple web application with which a user may author a message with attached files.
multiple html file inputs with javascript link http://img38.imageshack.us/img38/4474/attachments.gif
That "attach additional files" link does not yet work. It should add an additional file input control to the form each time it's clicked.
I need a JavaScript method addanotherfileinput() to replace the clicked anchor:
attach additional files
With this new table row, file input, and anchor:
<input type="file" name="Attachment1" id="Attachment1" class="textinput" />
</td>
</tr>
<tr>
<td></td>
<td>
attach additional files
And also increment the number: Attachment2, Attachment3, Attachment4, etc.
How can I do this?
You could use the DOM to dynamically insert the file inputs
var myTd = /* Get the td from the dom */
var myFile = document.createElement('INPUT');
myFile.type = 'file'
myFile.name = 'files' + i; // i is a var stored somewhere
i++;
myTd.appendChild(myFile);
OR you can use this
http://developer.yahoo.com/yui/examples/uploader/uploader-simple-button.html
You probably don't want to replace the anchor, just insert something in front of it.
I use Prototype for things like this, because it irons out a lot of browser inconsistencies, particularly around forms and tables.
Using Prototype, it would look something like this:
function insertFileField(element, index) {
element.insert({
before: "<input type='file' name='Attachment" + index + " class='textinput'>"
});
}
// And where you're hooking up your `a` element (`onclick` is very outdated,
// best to use unubtrustive JavaScript)
$('attachlink').observe('click', function(event) {
event.stop();
insertFileField(this, this.up('form').select('input[type=file]').length + 1);
});
...the bit at the end finds the form containing the link, finds out how many inputs of type file there are, and adds one for the index.
There are other ways as well, via the Element constructor provided by Prototype, but text works quite well (in fact, it's usually much faster).
It would be similar, though slightly different, with jQuery, MooTools, YUI, Glow, or any of the several other JavaScript frameworks.
There might be a better way, but I did this client side by creating a set of HTML form elements and then hiding/showing the rows using JavaScript to update the CSS class.
EDIT: I'll leave this here as an alternate method but I like the idea of adding INPUT elements through the DOM better.