Search Results

Search found 3629 results on 146 pages for 'nested divs'.

Page 54/146 | < Previous Page | 50 51 52 53 54 55 56 57 58 59 60 61  | Next Page >

  • Nested Routes Show Action: What objects does it expect?

    - by NoahClark
    Here is the relevant line from my rake routes: client_note GET /clients/:client_id/notes/:id(.:format) notes#show When I try passing in the objects like <%= client_note_path([client, @notes.first]) %>> I get: No route matches {:action=>"show", :controller=>"notes", :client_id=>[#<Client id: 5, ... , #<Note id: 9, ...]} Which made me think to try a client ID. So, I tried: <%= client_note_path([client.id, @notes.first]) %> which gives me: No route matches {:action=>"show", :controller=>"notes", :client_id=>[5, #<Note id: 9,content: "He just bought a brand new bobcat, be sure to charg...", client_id: 5, created_at: "2012-06-11 16:18:16", updated_at: "2012-06-11 16:18:16">]} Which, made me want to try just passing in a client ID. <%= client_note_path(client.id) %> No route matches {:action=>"show", :controller=>"notes", :client_id=>5} Still not what I'm looking for. I want to be able to show an individual note which can normally be found at a url like looks like: http://localhost:3000/clients/2/notes/3/

    Read the article

  • How do I find the highest level TR that contains a specific ID nested in a table

    - by Mykroft
    I have some HTML that looks like this (NOTE: I know this code isn't great but I didn't design it originally and some of it is auto generated): <table id="tab1"> <tr> <td><span>Some text</span></td> <td><span>more text</span></td> <td><input type="text" id="inp1" onclick="DoSomething(this);" /></td> </tr> <tr> <td><span>Some text</span></td> <td><span>more text</span></td> <td><table id="tab2"> <tr><td><input type="radio" id="inp2" onclick="DoSomething(this);" /><span>item</span></td></tr> </table></td> </tr> </table> All of that is embedded in a table which is also embedded in a table and so on. In the DoSomething(this) function I want to retrieve the TR underneath the table tab1. I'm having trouble figuring out the jquery necessary for this. Currently I'm doing something like this: function DoSomething(control) { var parentTab = '<%=tab1.ClientID %>'; var tr = $('#' + parentTab + ' > tbody > tr').has('#' + $(control).attr('id')).get(0); } This seems really messy but works. Is there a cleaner way to do this? If it helps the input inside the table will always be a radio button and a radio button will never appear outside of a sub table. Ideally I'd like to do this without having to know the id of tab1 but that seems impossible.

    Read the article

  • Equal Height Columns with Cross-Browser CSS

    - by Frank Michael Kraft
    I want to have divs of the same height. http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks does not work for be because my divs have a border, and the method described assumes, that they have not. A jQuery solution I could not make work, because my divs resize late because of ajax and menu clicks and I can not find an event for this.

    Read the article

  • How to implement "short" nested vanity urls in rails?

    - by UnSandpiper
    I understand how to create a vanity URL in Rails in order to translate http://mysite.com/forum/1 into http://mysite.com/some-forum-name But I'd like to take it a step further and get the following working (if it is possible at all): Instead of: http://mysite.com/forum/1/board/99/thread/321 I'd like in the first step to get to something like this: http://mysite.com/1/99/321 and ultimately have it like http://mysite.com/some-forum-name/some-board-name/this-is-the-thread-subject. Is this possible?

    Read the article

  • Change class of parent div if radio input checked

    - by xxstevenxo
    I've been searching and searching google for answers to my question but have been unsuccessful so far. I'm hoping one of you guys could give me some assistance. I have 10 divs with the class name "dividend" holding a table with the classname/id of "container" then two smaller tables inside that. Within the container table at the bottom is a hidden radio button with the name "page1". I wrote an onClcick for the container table so the user can select the whole table instead of the radio button, but not I'm trying to change the style of the selected container so the users know they have selected it. I have tried a few different methods and I'm able to change the style to the new class by just writing document.getElementById('container').className = 'selected'; But because all 10 divs share the same name it will only change the style of the first element it finds. So I tried writing this loop to check if there are any selected radios in the document then to change the else name the style as the default. I'm sure its something stupid but I'm pretty stumped atm.. Any help would be appreciated. Thanks. selected = function () { var divs = document.getElementByTagName('DIV'), div, tbl, rad, stat, i; for (i = 0; i < divs.length; i++) { div = divs.id; if (div == 'dividend') { tbl = div.getElementById('container'); rad = tbl.getElementByTagName('INPUT'); if (rad.checked = true) { tbl.className = 'selected'; } } } };

    Read the article

  • How do I access a value of a nested Perl hash?

    - by st
    I am new to Perl and I have a problem that's very simple but I cannot find the answer when consulting my Perl book. When printing the result of Dumper($request); I get the following result: $VAR1 = bless( { '_protocol' => 'HTTP/1.1', '_content' => '', '_uri' => bless( do{\(my $o = 'http://myawesomeserver.org:8081/counter/')}, 'URI::http' ), '_headers' => bless( { 'user-agent' => 'Mozilla/5.0 (X11; U; Linux i686; en; rv:1.9.0.4) Gecko/20080528 Epiphany/2.22 Firefox/3.0', 'connection' => 'keep-alive', 'cache-control' => 'max-age=0', 'keep-alive' => '300', 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'accept-language' => 'en-us,en;q=0.5', 'accept-encoding' => 'gzip,deflate', 'host' => 'localhost:8081', 'accept-charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7' }, 'HTTP::Headers' ), '_method' => 'GET', '_handle' => bless( \*Symbol::GEN0, 'FileHandle' ) }, 'HTTP::Server::Simple::Dispatched::Request' ); How can I access the values of '_method' ('GET') or of 'host' ('localhost:8081'). I know that's an easy question, but Perl is somewhat cryptic at the beginning.

    Read the article

  • in ruby, how do you make this nested hash work?

    - by David
    this one creates an error: @settings = { :tab1 => { :name => { :required => true }, :description } } need to change :descrpition to :description = {}, but i don't have any values for :description so i want it to remain as is (without the empty = {}) Would you show me the best way to handle this kind of situation? thanks in advance

    Read the article

  • Javascript/Jquery Super Scrollorama Navigation Issues

    - by Rosencruez
    On a Wordpress site I am currently working on, my client wanted the different sections of the front page to slide up from the bottom and cover up the previous section, like a wipe or slide transition. Using super scrollorama found here: http://johnpolacek.github.com/superscrollorama/, I managed to achieve the desired result. Next, I needed to create a navigation menu on the front page only. I did so, and set anchors at various different points on the pages. I also used the scrollTo library for scolling animations when I click the nav menu links. However, there are a number of problems I have encountered: When at the top and I click "showcase", it brings me down to the showcase section, but the products section (the div right after it) is overlapping it. Other divs seems to have the same problem of the following divs overlapping the current one I can only navigate forwards. When I try to go backwards, it won't (except for "Home") I thought it might have something to do with the CSS "top" property of the divs, so I tried resetting them every time the click function kicked in, but it didn't work. So I removed it for the time being. Currently set the javascript to prevent the default action of scrolling to the anchors and instead setting it to scroll to the actual divs themselves. However, I'm still having the same issues. Here is the site I am currently working on: http://breathe.simalam.ca/ Here is the javascript for the scrolling: $(document).ready(function() { jQuery('.home-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo(0, 1000, {queue:true}); }); jQuery('.showcase-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo('#showcase_content', 1000, {queue:true}); }); jQuery('.products-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo('#products_content', 1000, {queue:true}); }); jQuery('.about-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo('#about_content', 1000, {queue:true}); }); jQuery('.locator-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo('#locator_content', 1000, {queue:true}); }); jQuery('.contact-link').click(function(e){ e.preventDefault(); jQuery(window).scrollTo('#contact_content', 1000, {queue:true}); }); }); scrollorama code: $(document).ready(function() { $('#wrapper').css('display','block'); var controller = $.superscrollorama(); var pinDur = 4000; /* set duration of pin scroll in pixels */ // create animation timeline for pinned element var pinAnimations = new TimelineLite(); pinAnimations .append([ TweenMax.to($('#showcase'), .5, {css:{top:0}}) ], .5) .append([ TweenMax.to($('#products'), .5, {css:{top:0}}) ], .5) .append([ TweenMax.to($('#about'), .5, {css:{top:0}}) ], .5) .append([ TweenMax.to($('#locator'), .5, {css:{top:0}}) ], .5) .append([ TweenMax.to($('#contact'), .5, {css:{top:0}}) ], .5) .append(TweenMax.to($('#pin-frame-unpin'), .5, {css:{top:'100px'}})); controller.pin($('#examples-pin'), pinDur, { anim:pinAnimations, onPin: function() { $('#examples-pin').css('height','100%'); }, onUnpin: function() { $('#examples-pin').css('height','2000px'); } }); }); All of the section divs are inside a parent div. The section divs all have a height, width, and top of 100%. The parent div containing all of these section divs are as follows: #examples-pin { position: relative; /* relative positioning for transitions to work? */ width: 101%; /* max width */ height: 2000px; /* height of 2000px for now */ overflow: hidden; /* hide the overflow for transitions to work */ margin-bottom: -200px; /* negative bottom margin */ }

    Read the article

  • HTML block nested in PHP if statement - is this considered bad practice?

    - by JYelton
    Consider the following example: <table> <tr> <td>Row One</td> </tr> <?php if ($rowtwo) { ?> <tr> <td>Row Two</td> </tr> <?php } ?> </table> If $rowtwo is true, the second row is output, otherwise it is skipped. The code works as desired, however I am evaluating Netbeans (7 beta) as a PHP IDE (instead of just using a text editor). Netbeans flags the code with an error: Misplaced non-space characters insided [sic] a table. Should I consider an alternate way of writing this code, or is Netbeans incapable of understanding this flow control wrapper for HTML output?

    Read the article

  • PowerShell; Use Get-Member to Self Document Nested COM Object

    - by Zion
    Anyone know how to use Get-Member to Recursively dump to a text file The entire properties|methods tree of a COM object? (The Output formatting of Get-Object is fine) Instead of giving me only the top level as in this example; New-Object -com AutoItX3.Control | Get-Member I need it to recurse the entire object to return results. If This is not possible, how would I dump the methods/properties of a sub object?

    Read the article

  • Simpler / more efficient method of nested if ... else flow?

    - by Scott
    I'm currently working on an emulation server for a flash-client based game, which has a "pets system", and I was wondering if there was a simpler way of going about checking the level of specified pets. Current code: public int Level { get { if (Expirience > 100) // Level 2 { if (Expirience > 200) // Level 3 { if (Expirience > 400) // Level 4 - Unsure of Goal { if (Expirience > 600) // Level 5 - Unsure of Goal { if (Expirience > 1000) // Level 6 { if (Expirience > 1300) // Level 7 { if (Expirience > 1800) // Level 8 { if (Expirience > 2400) // Level 9 { if (Expirience > 3200) // Level 10 { if (Expirience > 4300) // Level 11 { if (Expirience > 7200) // Level 12 - Unsure of Goal { if (Expirience > 8500) // Level 13 - Unsure of Goal { if (Expirience > 10100) // Level 14 { if (Expirience > 13300) // Level 15 { if (Expirience > 17500) // Level 16 { if (Expirience > 23000) // Level 17 { return 17; // Bored } return 16; } return 15; } return 14; } return 13; } return 12; } return 11; } return 10; } return 9; } return 8; } return 7; } return 6; } return 5; } return 4; } return 3; } return 2; } return 1; } } Yes, I'm aware I've misspelt Experience, I had made the mistake in a previous function and hadn't gotten around to updating everything.

    Read the article

  • How do I add events to nested server controls? (ASP.Net)

    - by bert
    I am building a custom master page type control i.e. sort of like a datagrid but should be easier to add custom functionality into it. It's going great but part of the desired functionality is to have a paging control that switches on and off and part of that control would be a textbox that displays the current page number and on TextChanged redirects to the new page of the dataset. The problem I'm having is that technically the textbox which has its event fired is embedded in a control that is embedded in the control you actually put on the page sort of like Page  | Display Control  | Paging Control  | Textbox Buried all the way down there the event is not firing. Worse the postback javascript isn't even being written onto the page (Nothing on the page posts back so far this is the only bit that really needs to). I've been trawling around Google for quite a while now and picked up that I need to implement INamingContainer (done) and I need to add the control into the page's control tree (is Pre_Init too late for that? When's a good time to Add the Control to the page?) then the event should fire, apparently. But I've been unable to find an example of best practice on this there are quite a few near misses where people are having button angst but this isn't a button. So can anyone point me in the direction of getting a control embedded in a control embedded in a control added to a page to behave properly?

    Read the article

  • How to access a superclass method from a nested class?

    - by m01
    I hope this code explains the problem: class Foo { void a() { / *stuff */ } } class Bar extends Foo { void a() { throw new Exception("This is not allowed for Bar"); } class Baz { void blah() { // how to access Foo.a from here? } } } I know that I may be doing something wrong, because inheritance perhaps shouldn't be used in such way. But it's the easiest way in my situation. And, beside that, I'm just curious. Is it possible?

    Read the article

  • How do I push a new controller via UIButton, nested in a UIScrollView?

    - by jimijon
    Hello - I have my views that are part of a tabBar. Each view has a navigationController. In one of my views I have an embeded xib component. This is a scrolling view with UIButtons inside it. I want to slide in another view, inside the navigationController when a person taps the button. I can get the taps, etc. BUT, I can't figure out how to find the controlling navigationController of that page to push the new view into. Nothing seems to work that I have tried. IS this possible? Thanks

    Read the article

  • Is re-throwing an exception legal in a nested 'try'?

    - by Alexander Gessler
    Is the following well-defined in C++, or not? I am forced to 'convert' exceptions to return codes (the API in question is used by many C users, so I need to make sure all C++ exceptions are caught & handled before control is returned to the caller). enum ErrorCode {…}; ErrorCode dispatcher() { try { throw; } catch (std::bad_alloc&) { return ErrorCode_OutOfMemory; } catch (std::logic_error&) { return ErrorCode_LogicError; } catch (myownstdexcderivedclass&) { return ErrorCode_42; } catch(...) { return ErrorCode_UnknownWeWillAllDie; } } ErrorCode apifunc() { try { // foo() might throw anything foo(); } catch(...) { // dispatcher rethrows the exception and does fine-grained handling return dispatcher(); } return ErrorCode_Fine; } ErrorCode apifunc2() { try { // bar() might throw anything bar(); } catch(...) { return dispatcher(); } return ErrorCode_Fine; } I hope the sample shows my intention. My guess is that this is undefined behaviour, but I'm not sure. Please provide quotes from the standard, if applicable. Alternative approaches are appreciated as well. Thanks!

    Read the article

  • Nested modal view controller gives strange message under iOS6?

    - by user1840362
    I am presenting a modal view controller from another modal view controller, and this worked fine under all iOS versions prior to iOS6. But under iOS6 I am getting the following warning message in the emulator: Warning: Attempt to present <UINavigationController: 0x14e93680> on <UINavigationController: 0x9fc6b70> while a presentation is in progress! The modal view controller is not shown if this warning appears. Basically I am using code like this to show the modal view controller: WebAuthViewController *authController = [[WebAuthViewController alloc] initWithNibName:nil bundle:nil]; authController.challenge = challenge; authController.delegate = self; UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:authController]; [self presentModalViewController:aNavController animated:YES]; [aNavController release]; [authController release]; The view that is already shown is a UIWebView also shown in a modal view, like this: WebViewController *addController = [[WebViewController alloc] initWithNibName:nil bundle:nil]; addController.urlToLoad = [NSURL URLWithString:urlString]; addController.delegate = self; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addController]; navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self presentModalViewController:navigationController animated:YES]; [navigationController release]; [addController release]; The apple docs still suggest that one is supposed to be able to stack navigation controllers like this, so I am at a loss to explain why this happens. Any hints?

    Read the article

  • How to make a SUM of Dictionary Value nested into a list with LINQ ?

    - by user551108
    Hi All, I have a product object declared as : Product { int ProductID; string ProductName; int ProductTypeID; string ProductTypeName; int UnitsSold Dictionary <string, int> UnitsSoldByYear; } I want to make a sum on UnitsSold and UnitsSoldByYear properties with a Linq query but I didn't know how to make this kind of sum on a dictionary ! Here is my begining linq query code : var ProductTypeSum = from i in ProductsList group i by new { i.ProductTypeID, i.ProductTypeName} into pt select new { ProductTypeID= pt.Key.ProductTypeID, ProductTypeName= pt.Key.ProductTypeName, UnitsSoldSum= pt.Sum(i => i.UnitsSold), // How to make a Dictionary sum here } Thank you for your help !

    Read the article

  • Timing issue with jQuery and $(document).ready()

    - by ripper234
    I have the following code block code when the document is ready: $(document).ready(function() { createDivs(); // creates some divs with class 'foo'; // iterate $(".foo").each(function(index) { alert(index + " - " + $(this).text()); }); } I find that the "iterate" part misses the divs I created in the createDivs() method entirely! Is there some timing issue I'm not aware of? Why doesn't jquery see the divs that were just created?

    Read the article

  • Why can't my vector access the variables in my nested structs?

    - by chucknorris
    #include<iostream> #include<vector> #include<string> #include<list> using namespace std; struct record{ int id; string fName; }; struct cells{ list<record> rec; }; vector<cells> hp; int main() { **hp.front().rec.front().fName = "jon"; return 0; } I have 2 structs. The first struct, struct record, is composed of 2 regular variables. In struct 2, I have a linked list of type "record", which includes all the variable listed in struct 1. Why is it that when ever I attempt to access a variable in the structs, using my vector, I get the error "linked list iterator not dereferencable?"

    Read the article

  • How do I do "nested if" in JSTL for Java JSP?

    - by user678616
    I want to do something like the following: <c:choose> <c:when test="${empty example1}"> </c:when> <c:otherwise> <c:when test="${empty example2}"> </c:when> <c:otherwise> </c:otherwise> </c:otherwise> </c:choose> Is this even possible? I get an exception thrown when trying to run. Thank you.

    Read the article

  • Basics of Join Predicate Pushdown in Oracle

    - by Maria Colgan
    Happy New Year to all of our readers! We hope you all had a great holiday season. We start the new year by continuing our series on Optimizer transformations. This time it is the turn of Predicate Pushdown. I would like to thank Rafi Ahmed for the content of this blog.Normally, a view cannot be joined with an index-based nested loop (i.e., index access) join, since a view, in contrast with a base table, does not have an index defined on it. A view can only be joined with other tables using three methods: hash, nested loop, and sort-merge joins. Introduction The join predicate pushdown (JPPD) transformation allows a view to be joined with index-based nested-loop join method, which may provide a more optimal alternative. In the join predicate pushdown transformation, the view remains a separate query block, but it contains the join predicate, which is pushed down from its containing query block into the view. The view thus becomes correlated and must be evaluated for each row of the outer query block. These pushed-down join predicates, once inside the view, open up new index access paths on the base tables inside the view; this allows the view to be joined with index-based nested-loop join method, thereby enabling the optimizer to select an efficient execution plan. The join predicate pushdown transformation is not always optimal. The join predicate pushed-down view becomes correlated and it must be evaluated for each outer row; if there is a large number of outer rows, the cost of evaluating the view multiple times may make the nested-loop join suboptimal, and therefore joining the view with hash or sort-merge join method may be more efficient. The decision whether to push down join predicates into a view is determined by evaluating the costs of the outer query with and without the join predicate pushdown transformation under Oracle's cost-based query transformation framework. The join predicate pushdown transformation applies to both non-mergeable views and mergeable views and to pre-defined and inline views as well as to views generated internally by the optimizer during various transformations. The following shows the types of views on which join predicate pushdown is currently supported. UNION ALL/UNION view Outer-joined view Anti-joined view Semi-joined view DISTINCT view GROUP-BY view Examples Consider query A, which has an outer-joined view V. The view cannot be merged, as it contains two tables, and the join between these two tables must be performed before the join between the view and the outer table T4. A: SELECT T4.unique1, V.unique3 FROM T_4K T4,            (SELECT T10.unique3, T10.hundred, T10.ten             FROM T_5K T5, T_10K T10             WHERE T5.unique3 = T10.unique3) VWHERE T4.unique3 = V.hundred(+) AND       T4.ten = V.ten(+) AND       T4.thousand = 5; The following shows the non-default plan for query A generated by disabling join predicate pushdown. When query A undergoes join predicate pushdown, it yields query B. Note that query B is expressed in a non-standard SQL and shows an internal representation of the query. B: SELECT T4.unique1, V.unique3 FROM T_4K T4,           (SELECT T10.unique3, T10.hundred, T10.ten             FROM T_5K T5, T_10K T10             WHERE T5.unique3 = T10.unique3             AND T4.unique3 = V.hundred(+)             AND T4.ten = V.ten(+)) V WHERE T4.thousand = 5; The execution plan for query B is shown below. In the execution plan BX, note the keyword 'VIEW PUSHED PREDICATE' indicates that the view has undergone the join predicate pushdown transformation. The join predicates (shown here in red) have been moved into the view V; these join predicates open up index access paths thereby enabling index-based nested-loop join of the view. With join predicate pushdown, the cost of query A has come down from 62 to 32.  As mentioned earlier, the join predicate pushdown transformation is cost-based, and a join predicate pushed-down plan is selected only when it reduces the overall cost. Consider another example of a query C, which contains a view with the UNION ALL set operator.C: SELECT R.unique1, V.unique3 FROM T_5K R,            (SELECT T1.unique3, T2.unique1+T1.unique1             FROM T_5K T1, T_10K T2             WHERE T1.unique1 = T2.unique1             UNION ALL             SELECT T1.unique3, T2.unique2             FROM G_4K T1, T_10K T2             WHERE T1.unique1 = T2.unique1) V WHERE R.unique3 = V.unique3 and R.thousand < 1; The execution plan of query C is shown below. In the above, 'VIEW UNION ALL PUSHED PREDICATE' indicates that the UNION ALL view has undergone the join predicate pushdown transformation. As can be seen, here the join predicate has been replicated and pushed inside every branch of the UNION ALL view. The join predicates (shown here in red) open up index access paths thereby enabling index-based nested loop join of the view. Consider query D as an example of join predicate pushdown into a distinct view. We have the following cardinalities of the tables involved in query D: Sales (1,016,271), Customers (50,000), and Costs (787,766).  D: SELECT C.cust_last_name, C.cust_city FROM customers C,            (SELECT DISTINCT S.cust_id             FROM sales S, costs CT             WHERE S.prod_id = CT.prod_id and CT.unit_price > 70) V WHERE C.cust_state_province = 'CA' and C.cust_id = V.cust_id; The execution plan of query D is shown below. As shown in XD, when query D undergoes join predicate pushdown transformation, the expensive DISTINCT operator is removed and the join is converted into a semi-join; this is possible, since all the SELECT list items of the view participate in an equi-join with the outer tables. Under similar conditions, when a group-by view undergoes join predicate pushdown transformation, the expensive group-by operator can also be removed. With the join predicate pushdown transformation, the elapsed time of query D came down from 63 seconds to 5 seconds. Since distinct and group-by views are mergeable views, the cost-based transformation framework also compares the cost of merging the view with that of join predicate pushdown in selecting the most optimal execution plan. Summary We have tried to illustrate the basic ideas behind join predicate pushdown on different types of views by showing example queries that are quite simple. Oracle can handle far more complex queries and other types of views not shown here in the examples. Again many thanks to Rafi Ahmed for the content of this blog post.

    Read the article

  • c# Truncate HTML safely for article summary

    - by WickedW
    Hi All, Does anyone have a c# variation of this? This is so I can take some html and display it without breaking as a summary lead in to an article? http://stackoverflow.com/questions/1193500/php-truncate-html-ignoring-tags Save me from reinventing the wheel! Thank you very much ---------- edit ------------------ Sorry, new here, and your right, should have phrased the question better, heres a bit more info I wish to take a html string and truncate it to a set number of words (or even char length) so I can then show the start of it as a summary (which then leads to the main article). I wish to preserve the html so I can show the links etc in preview. The main issue I have to solve is the fact that we may well end up with unclosed html tags if we truncate in the middle of 1 or more tags! The idea I have for solution is to a) truncate the html to N words (words better but chars ok) first (be sure not to stop in the middle of a tag and truncate a require attribute) b) work through the opened html tags in this truncated string (maybe stick them on stack as I go?) c) then work through the closing tags and ensure they match the ones on stack as I pop them off? d) if any open tags left on stack after this, then write them to end of truncated string and html should be good to go!!!! -- edit 12112009 Here is what I have bumbled together so far as a unittest file in VS2008, this 'may' help someone in future My hack attempts based on Jan code are at top for char version + word version (DISCLAIMER: this is dirty rough code!! on my part) I assume working with 'well-formed' HTML in all cases (but not necessarily a full document with a root node as per XML version) Abels XML version is at bottom, but not yet got round to fully getting tests to run on this yet (plus need to understand the code) ... I will update when I get chance to refine having trouble with posting code? is there no upload facility on stack? Thanks for all comments :) using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace PINET40TestProject { [TestClass] public class UtilityUnitTest { public static string TruncateHTMLSafeishChar(string text, int charCount) { bool inTag = false; int cntr = 0; int cntrContent = 0; // loop through html, counting only viewable content foreach (Char c in text) { if (cntrContent == charCount) break; cntr++; if (c == '<') { inTag = true; continue; } if (c == '>') { inTag = false; continue; } if (!inTag) cntrContent++; } string substr = text.Substring(0, cntr); //search for nonclosed tags MatchCollection openedTags = new Regex("<[^/](.|\n)*?>").Matches(substr); MatchCollection closedTags = new Regex("<[/](.|\n)*?>").Matches(substr); // create stack Stack<string> opentagsStack = new Stack<string>(); Stack<string> closedtagsStack = new Stack<string>(); // to be honest, this seemed like a good idea then I got lost along the way // so logic is probably hanging by a thread!! foreach (Match tag in openedTags) { string openedtag = tag.Value.Substring(1, tag.Value.Length - 2); // strip any attributes, sure we can use regex for this! if (openedtag.IndexOf(" ") >= 0) { openedtag = openedtag.Substring(0, openedtag.IndexOf(" ")); } // ignore brs as self-closed if (openedtag.Trim() != "br") { opentagsStack.Push(openedtag); } } foreach (Match tag in closedTags) { string closedtag = tag.Value.Substring(2, tag.Value.Length - 3); closedtagsStack.Push(closedtag); } if (closedtagsStack.Count < opentagsStack.Count) { while (opentagsStack.Count > 0) { string tagstr = opentagsStack.Pop(); if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek()) { substr += "</" + tagstr + ">"; } else { closedtagsStack.Pop(); } } } return substr; } public static string TruncateHTMLSafeishWord(string text, int wordCount) { bool inTag = false; int cntr = 0; int cntrWords = 0; Char lastc = ' '; // loop through html, counting only viewable content foreach (Char c in text) { if (cntrWords == wordCount) break; cntr++; if (c == '<') { inTag = true; continue; } if (c == '>') { inTag = false; continue; } if (!inTag) { // do not count double spaces, and a space not in a tag counts as a word if (c == 32 && lastc != 32) cntrWords++; } } string substr = text.Substring(0, cntr) + " ..."; //search for nonclosed tags MatchCollection openedTags = new Regex("<[^/](.|\n)*?>").Matches(substr); MatchCollection closedTags = new Regex("<[/](.|\n)*?>").Matches(substr); // create stack Stack<string> opentagsStack = new Stack<string>(); Stack<string> closedtagsStack = new Stack<string>(); foreach (Match tag in openedTags) { string openedtag = tag.Value.Substring(1, tag.Value.Length - 2); // strip any attributes, sure we can use regex for this! if (openedtag.IndexOf(" ") >= 0) { openedtag = openedtag.Substring(0, openedtag.IndexOf(" ")); } // ignore brs as self-closed if (openedtag.Trim() != "br") { opentagsStack.Push(openedtag); } } foreach (Match tag in closedTags) { string closedtag = tag.Value.Substring(2, tag.Value.Length - 3); closedtagsStack.Push(closedtag); } if (closedtagsStack.Count < opentagsStack.Count) { while (opentagsStack.Count > 0) { string tagstr = opentagsStack.Pop(); if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek()) { substr += "</" + tagstr + ">"; } else { closedtagsStack.Pop(); } } } return substr; } public static string TruncateHTMLSafeishCharXML(string text, int charCount) { // your data, probably comes from somewhere, or as params to a methodint XmlDocument xml = new XmlDocument(); xml.LoadXml(text); // create a navigator, this is our primary tool XPathNavigator navigator = xml.CreateNavigator(); XPathNavigator breakPoint = null; // find the text node we need: while (navigator.MoveToFollowing(XPathNodeType.Text)) { string lastText = navigator.Value.Substring(0, Math.Min(charCount, navigator.Value.Length)); charCount -= navigator.Value.Length; if (charCount <= 0) { // truncate the last text. Here goes your "search word boundary" code: navigator.SetValue(lastText); breakPoint = navigator.Clone(); break; } } // first remove text nodes, because Microsoft unfortunately merges them without asking while (navigator.MoveToFollowing(XPathNodeType.Text)) { if (navigator.ComparePosition(breakPoint) == XmlNodeOrder.After) { navigator.DeleteSelf(); } } // moves to parent, then move the rest navigator.MoveTo(breakPoint); while (navigator.MoveToFollowing(XPathNodeType.Element)) { if (navigator.ComparePosition(breakPoint) == XmlNodeOrder.After) { navigator.DeleteSelf(); } } // moves to parent // then remove *all* empty nodes to clean up (not necessary): // TODO, add empty elements like <br />, <img /> as exclusion navigator.MoveToRoot(); while (navigator.MoveToFollowing(XPathNodeType.Element)) { while (!navigator.HasChildren && (navigator.Value ?? "").Trim() == "") { navigator.DeleteSelf(); } } // moves to parent navigator.MoveToRoot(); return navigator.InnerXml; } [TestMethod] public void TestTruncateHTMLSafeish() { // Case where we just make it to start of HREF (so effectively an empty link) // 'simple' nested none attributed tags Assert.AreEqual(@"<h1>1234</h1><b><i>56789</i>012</b>", TruncateHTMLSafeishChar( @"<h1>1234</h1><b><i>56789</i>012345</b>", 12)); // In middle of a! Assert.AreEqual(@"<h1>1234</h1><a href=""testurl""><b>567</b></a>", TruncateHTMLSafeishChar( @"<h1>1234</h1><a href=""testurl""><b>5678</b></a><i><strong>some italic nested in string</strong></i>", 7)); // more Assert.AreEqual(@"<div><b><i><strong>1</strong></i></b></div>", TruncateHTMLSafeishChar( @"<div><b><i><strong>12</strong></i></b></div>", 1)); // br Assert.AreEqual(@"<h1>1 3 5</h1><br />6", TruncateHTMLSafeishChar( @"<h1>1 3 5</h1><br />678<br />", 6)); } [TestMethod] public void TestTruncateHTMLSafeishWord() { // zero case Assert.AreEqual(@" ...", TruncateHTMLSafeishWord( @"", 5)); // 'simple' nested none attributed tags Assert.AreEqual(@"<h1>one two <br /></h1><b><i>three ...</i></b>", TruncateHTMLSafeishWord( @"<h1>one two <br /></h1><b><i>three </i>four</b>", 3), "we have added ' ...' to end of summary"); // In middle of a! Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four ...</b></a>", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four five </b></a><i><strong>some italic nested in string</strong></i>", 4)); // start of h1 Assert.AreEqual(@"<h1>one two three ...</h1>", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 3)); // more than words available Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i> ...", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 99)); } [TestMethod] public void TestTruncateHTMLSafeishWordXML() { // zero case Assert.AreEqual(@" ...", TruncateHTMLSafeishWord( @"", 5)); // 'simple' nested none attributed tags string output = TruncateHTMLSafeishCharXML( @"<body><h1>one two </h1><b><i>three </i>four</b></body>", 13); Assert.AreEqual(@"<body>\r\n <h1>one two </h1>\r\n <b>\r\n <i>three</i>\r\n </b>\r\n</body>", output, "XML version, no ... yet and addeds '\r\n + spaces?' to format document"); // In middle of a! Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four ...</b></a>", TruncateHTMLSafeishCharXML( @"<body><h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four five </b></a><i><strong>some italic nested in string</strong></i></body>", 4)); // start of h1 Assert.AreEqual(@"<h1>one two three ...</h1>", TruncateHTMLSafeishCharXML( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 3)); // more than words available Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i> ...", TruncateHTMLSafeishCharXML( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 99)); } } }

    Read the article

< Previous Page | 50 51 52 53 54 55 56 57 58 59 60 61  | Next Page >