I am using jquery 1.6.4 and I have a table. Initially in the table, a user is presented by only one row and a few columns. I, then, let users add as many rows as they would like using by doing this
$('.add').live('click', function(e){
e.preventDefault();
var $parentRow = $(this).parents('tr');
$parentRow.clone().insertAfter($parentRow);
$parentRow.next().find('input').val('');
$(this).replaceWith('-');
});
I also let them delete the rows on fly doing this
$('.delete').live('click', function(e){
alert("removing");
e.preventDefault();
$(this).parents('tr').remove();
});
However now I want the values that they are entering in these columns to be collected. I am not sure how to collect those values when they hit submit button as in my view source all I see is this
<tr>
<td class="actions">+</td>
<td><input type="text"></input></td>
<td><input type="text"></input></td>
<td><input type="text"></input></td>
<td><textarea rows="1"></textarea></td>
</tr>
In the page source it shows only one row where as in my view I definitely see three rows added. Not sure what am I missing and how to get the values
You don't have ids so it will be difficult to tell what you are actually collecting, but to get the values of the inputs, both static and dynamic, you can use this:
//submit code
$('input[type=submit]').click(function(){
$('table input').each(function(index,item){
//for testing you could just output to a div
//$('#output').append($(this).val());
});
});
From what I can tell, your input fields don't have names, so you're not going to get much when submit is pressed.
Also, you won't see DOM updates in your view source. View source will only show you what the page looked like when it first loaded.
To get a live view of the page, you can either use FireBug, for FireFox, or if you're using Google Chrome, there are developer tools under the "View" menu that you can use to see how the html looks live.
Related
I've been working with Knockout.js for some time now but only recently I've started to integrate jqueryUI animations for the sake of a better user experience. I'm seeing some issues trying to use the animation bindings on the tr elements inside a table tag. When I use the "visible" binding to hide and show each element it works just fine but when I attempt to animate the showing hiding of each element it only seems to apply to the first row in the table. I've attempted this using various methods. I've attempted using the knockout foreach template 'afterAdd' option as described here:
http://knockoutjs.com/documentation/foreach-binding.html#note_5_postprocessing_or_animating_the_generated_dom_elements
I've also created a custom binding and attempted to use that on each of the table row items with the same results.
Lastly I attempted to use the plugin found here:
http://www.codecoding.com/knockout-plugin-visibility-bindings-with-jqueryui-effects/
And again, it only appears to work on the first element of the table. Now before attempting to rewrite my HTML to use divs and spans rather than the tables I wanted to see if anybody else has seen these sorts of issues with knockout in the past. The relevant chunk of HTML is this:
<table class="tab_table table_a">
<tbody data-bind="foreach:featuredMenuItems,visible:showFeatured">
<tr data-bind="fadeVisible:readyToShow, click:function(){$root.showProductOptions($data);}">
<td class="td_large" data-bind="css:{td_select:itemInCart};"><span class="inCart_delete" data-bind="css:{display_IB:itemInCart},click:removeFromCart,clickBubble:false"><i class="fa fa-times-circle"></i></span><span data-bind="text:name"></span></td>
<td class="td_last" data-bind="css:{td_select:itemInCart},text:lineItemCost"></td>
</tr>
</tbody>
</table>
I would paste the ViewModel code in here as well but it is a rather large view model and the relevant part to this is just a simple "readyToShow" observable set to either true or false. Whenever this table is being shown the "readyToShow" values of each of the objects in the observableArray containing the table items is being set to true over time using a timeout so as to show a cascading effect when the table is shown.
I would really appreciate any help you guys could provide. Thanks!
In a Chrome Packaged app, using angular.dart, in a component html I have the below table which is dispaying paginated contents of an object list; exp. jobs :
<tbody>
<tr id="{{job.jobID}}" ng-repeat="job in jComp.jobs | pagination:jComp.paginator.instance" ng-model="job" ng-click="jComp.selectJob(job.jobID)">
<td>{{job.jobID}}</td>
<td>
{{job.productID}}<br>
{{job.productDescription}}<br>
</td>
<td>{{job.productType}}</td>
<td><img alt="No thumb" ng-src="{{job.thumbFURL}}"/></td>
<td>{{job.status}}</td>
</tr>
</tbody>
then in my component I am showing a popup modal div to ask user to choose an action. When the user clicks to change the job.status, there is a second layer of confirmation modal, and once confirmed in the component I am finding the job from the jComp.jobs List and updating the status. In side the popup modal the status gets updated but on the table it still shows the old status. And then when I paginate to next page and come back it gets updated. Before page switch it stays the same ? I tried calling scope.apply() after updating the jobs list, but it doesn't help. I like to know what is paginator.goNext() or paginator.goPrev() doing that causes the table list to refresh. Not clear about how the two way data binding working in this scenario. ( pagination is done using angular_pagination package )
I tried using :
<td ng-bind="job.status"/>
instead of:
<td>{{job.status}}</td>
and it fixed this issue. I am not sure why double brackets were not registering the object in the list to the change listeners / watchers. As far as I understand two way binding should be working with {{}} but in this case something was breaking it. It might be a bug in double brackets.
I am working on Infragistics Grid in MVC and want to do some customization in it.
The issue is that data which I am showing is different than the inputs I am taking from the user (the editors in row editing/adding mode). There is additional processing needed to be done before displaying in a grid.
Infragistics grid provides a good mechanism to show the JSON object array which nice UI and events which works fine for me. The problem comes when I want to Edit a particular Row or Add New. For this Infragistics provides its own UI for it. Or in case we want to customize it, it doesn't provide much room to do so. It just allows providing a template for columns like the following:
<script id="rowEditDialogRowTemplate1" type="text/x-jquery-tmpl">
<tr class="tableBackGround">
<td class="labelBackGround"> ${headerText}
</td>
<td data-key='${dataKey}'>
<input />
</td>
</tr>
</script>
But I want to provide an entire template which will have my custom form and form elements.
I want a simple Infragistics Grid which will just show the data. If I click Add New within the grid then it will load my dialog.
If I double-click any row it will again open my dialog where I can edit the things. Later, once I save the data, I'll make a server trip and refresh the grid accordingly.
To summarize
I want to provide my own custom Form for Add and Edit in Infragistics Grid. And I'll take care of reloading the Grid after saving the data.
Reference : Infragistics Grid
Please help me to get this done!
You have found the correct API reference - in the 'options' tab look for the rowEditDialogTemplate option.
The use of the default Row Edit Template (yes, it can be used for adding rows as well) is shown in the official sample.
You can also find out more about it in the help topics: Row Edit Template and Configuring Row Edit Template.
Also, in the Infragistics forums you can find additional info on how to utilize the igGridUpdating feature's API methods (addRow and updateRow for example) with your fully custom form for row adding and editing.
Here's the thing: file a.php contains jQuery Tablesorter table.
This is the Tablesorter code:
$("#feedsTable thead").live("click", function() {
$("#feedsTable").tablesorter({
widthFixed : true,
dateFormat : "uk",
}).tablesorterPager({
container : $("#pager"),
positionFixed : false
});
});
Slightly stripped table HTML code:
<div id="tablica">
<article class="module width_full">
<div id="pager">
<form>
[snip]tablesort pager stuff...
</form>
</div>
<table id="feedsTable" class="tablesorter" cellspacing="0">
<thead>
<tr>
[snip]table header row...
</tr>
</thead>
<tbody> ... PHP printed table data
Also, file a.php contains refresh link, which, when clicked, calls b.php file which contains following code: $("#tablica").load("a.php #tablica"); (basically, b.php prints table with new elements and then replaces the old table with the new one using the load function).
Of course, I must use either jQuery live or delegate (having some kind of problems with this one, just can't get Tablesorter to work, so I'm using live instead) function instead of (document).ready because once the load code is executed, Tablesorter will not work with the new table data.
But the problem is that when I use jQuery live() function, I need to click twice to be able to use the Tablesorter plugin. It's like the first click only "activates" the plugin, and then, when table header is clicked for 2nd time, table is sorted and it works great.
In a.php, I can add this code
$(document).ready(function() {
$("#feedsTable thead").click();
});
and it will "activate" the plugin and first user's click on the table header will sort the table. But if I add $("#feedsTable thead").click(); to the b.php file and click refresh link, this "hack" does not work, and again two clicks are needed to be able to use Tablesorter plugin after the table with new data is loaded.
Basically, the question is: I would like Tablesorter to work on first click when using jQuery live, and not only on second. How to fix that?
Any help would be much appreciated!
Thanks.
"of course, I must use either jQuery live or delegate"
http://api.jquery.com/live/:
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
Try on() and see if it makes much of a difference. If it doesn't then something else is at play.
So, delegate won't work because it is targeting the table inside of #tablica which has all of its contents completely replaced by the load function. Delegate needs an "anchor" element to detect a bubbling event whereas live uses the document, I think. So, the way it is written, when the user clicks anywhere in the thead, tablesorter will initialize. Now a second click will actually sort the column because tablesorter is active.
Anyway, the solution would be to initialize tablesorter within the load callback function. So remove the live function completely and try just this:
$("#tablica").load("a.php #tablica", function(){
$("#feedsTable").tablesorter({
widthFixed : true,
dateFormat : "uk",
}).tablesorterPager({
container : $("#pager"),
positionFixed : false
});
});
Now when the user clicks on the table header it will sort because tablesorter is initialized immediately after the content is loaded.
I'm working with ASP.NET MVC 2 and building a simple business app. Here are some of the details:
The app deals with work orders and
has a work order index view. The
view has a table listing the work
orders, and several controls (text
boxes, check boxes, and drop down
lists) to select the criteria for
which work orders to display.
I'm using viewmodels. The work order
index view has a viewmodel with
properties for each and every
control.
I've implemented paging similar to
what is being done in the answer to
this question:
How do I do pagination in ASP.NET MVC?
I'm using LINQ's Skip() and Take() as
demonstrated, and ActionLinks for the
navigation.
If I load the page and don't
manipulate any of the controls, I can
click on the page number ActionLinks
and move around just fine between
pages of work orders. However, if I
change something, my changes are lost
when I navigate to another page.
For example, if I'm on page 1 and
click an unchecked check box, and
then click on the link for page 2,
the second page of results will load
but the check box will revert to its
previous state.
I understand why this happens, but I'm wondering what is the best thing to do from a design standpoint.
Potential solutions I can think of:
Set all the control values as route
values in the ActionLinks. This
seems really nasty, and could result
in very long URLs or query strings. Actually, now that I think of it this wouldn't work without a way to capture the control values.
Since ActionLinks don't post
anything, replace them with buttons.
Again, this seems like a bad idea.
Change the ActionLinks to links that
fire off a jQuery script that does a
POST. I think this is the most
promising option so far. Do many
developers do it this way?
This seems like a common enough problem, but none of these options feel quite right. I wonder if I'm missing something.
Can't you just save the changes back to the database when the user toggles the checkboxes (using jQuery):
$("input[type=checkbox]").click(function() {
$.ajax({
type: "POST",
url: "/ControllerName/SaveInfo?id=" + {id},
success: function(){
alert("Data Saved: " + msg);
}
});
});
In the end, I wound up getting rid of the ActionLinks for the paging, and replaced them with regular anchor tags. The current page index is now stored in a hidden form value:
<input id="page" name="page" type="hidden" value="" />
<p>
<% for (var i = 1; i <= (int)Math.Ceiling(Model.RowsMatchingCriteria / (double)Model.PageSize); i++) { %>
<%--
If the page number link being rendered is the current page, don't add the href attribute.
That makes the link non-clickable.
--%>
<a class="pageLink" <%= i != Model.Page ? #"href=""javascript:void(0);""" : string.Empty %>><%: i %></a>
<% } %>
</p>
Then I added the following jQuery script, which sets the hidden page value and submits the form when a link is clicked:
$(document).ready(function () {
$('.pageLink:[href]').click(function () {
$('#page').val($(this).text()); // Set hidden field value to the text of the page link, which is the page number.
$('form:first').submit();
});
});
Problem solved.
Best bet is to effectively simulate viewstate by "logging" the changes to a hidden field when a user paginates. To do so:
1) Figure out what data you need to capture and a data format to do so in {ie -- an array of json objects}
2) Setup the link that handles the prev/next to fire off a method to collect the "changed" things and stuff them into objects and into a hidden field.
3) When posting the form, parse the hidden field, extract data and profit.