Using the feed icon images for each export link is not always the best option. In many use cases, end users would rather see a simple text link that can be styled. For example, on a few sites we only output on export link and it shows the 'XML' icon as the link. It would be better if we had the ability to change the attached text and have that display as the link that would be great.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

zhuber’s picture

Assigned: zhuber » Unassigned
Status: Needs work » Needs review
FileSize
3.17 KB

I've patched this so the view settings allow for image and text link options (checkbox).

Here is my author info, for attribution:
--author="zhuber <zhuber@1437276.no-reply.drupal.org>"

If my patch is committed, please attribute. Thanks

Status: Needs review » Needs work

The last submitted patch, 1: views_data_export-text_link-2261167.patch, failed testing.

zhuber’s picture

Status: Needs work » Needs review
FileSize
2.87 KB

Fixed the patch to use the correct relative path (hopefully).

Status: Needs review » Needs work

The last submitted patch, 3: views_data_export-text_link-2261167.patch, failed testing.

zhuber’s picture

Status: Needs work » Needs review
FileSize
2.76 KB

Ok, let's try this again.

zhuber’s picture

Status: Needs review » Reviewed & tested by the community

This has passed testing, can we get a final review and port this into the module?

Danny Englander’s picture

This works great, thank you for the patch, I just ran some tests and it works as expected. It would be great to get this in to dev or a release.

Danny Englander’s picture

Status: Reviewed & tested by the community » Needs work

Note, I just noticed that if you filter on a view and then download the data, the downloaded data is not filtered. Simply removing this patch fixes that and the downloaded data file inherits the filtered data from the page. For context, see #1871560: Exposed input not set on batch exports and #1322816: views data export - exposed filters

silurius’s picture

Confirmed (#8). You can also simply uncheck "Show link as image" in the format settings to make the downloaded data inherit the page's filtered data; removing the patch isn't strictly necessary.

Danny Englander’s picture

Well that's true, the whole reason I was testing the patch is that for our use case, we'd like a text link. There is no point in keeping the patched module if it does not serve any purpose. In the end, I simply grabbed the alt tag from the image and created a text only link and removed the image via jquery, it works like a charm.

silurius’s picture

There is no point in keeping the patched module if it does not serve any purpose.

Agreed. :)

In the end, I simply grabbed the alt tag from the image and created a text only link...

How/where did you create the text-only link? Been poking through the files and haven't found where to do that.

...and removed the image via jquery...

Was planning on doing this in CSS, myself. E.g., .view-display-id-my-display-name .feed-icon img {display:none;}.

Danny Englander’s picture

FileSize
15.37 KB

Here's what I did. I actually wanted the feed link at the top of the page so in my custom views-view file, I added this:

<?php if ($exposed): ?>
    <div class="view-filters">
      <?php if(isset($view->feed_icon)): ?>
        <div class="feed-icon-wrapper">
          <?php print $view->feed_icon; ?>
        </div>
      <?php endif; ?>
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

My view name for the above is contacts so my custom views-view file is: views-view--contacts--page.tpl.php

Then in jQuery I do this:

     // Theme the feed icon wrapper.
      $('.feed-icon-wrapper img').each(function (i, ele) {
        var alt = this.alt;
      $(this).after("<span " + "class='img-caption'>" + this.alt + "</span>");
        $(this).parent('a').addClass('views-data-export');
        $(this).remove();
      });

Now the <a> link has a class with which to theme and the image is removed. Note, I am also using font-awesome here to add the icon to the button via the CSS :after property.

silurius’s picture

Nicely done and well documented, much appreciated!

ressa’s picture

Thanks for sharing Danny, it works beautifully.

andileco’s picture

Thanks, Danny! This worked for me on load, but when I filtered (using Ajax), it reverted to an image. People may want to try this instead:

$('.content').bind("DOMSubtreeModified",function(){
   $('.feed-icon img').each(function (i, ele) {
        var alt = this.alt;
      $(this).replaceWith("<span " + "class='img-caption'>" + this.alt + "</span>");
        $(this).parent('a').addClass('views-data-export');
        $(this).remove();
      });  
});

A few important notes:
- rather than .content, you may want to use a more specific class or ID
- I didn't do the same template changes, so I used .feed-icon instead of .feed-icon-wrapper
- changed after to replaceWith

I think we should still push for an option in the module where you can select if you want an image or a text link, as what we're doing here is just a work-around.

Danny Englander’s picture

@andile2012 - interesting, I have some ajax filters on my views but did not run into that issue but knowing how weird ajax and drupal can be sometimes, I am not surprised this happened. Thanks for the tip!

andileco’s picture

I was also using Better Exposed Filters, so that may have played into it as well.

andileco’s picture

I was too excited with post #15 - it worked for me in Chrome, but not Firefox. I've switched to the following code:

function changeIconToText(){
  
   $('.feed-icon img').each(function (i, ele) {
		$(this).replaceWith("");
	  });
	  
	  if($('.feed-icon').find('a').text() == ''){
  		$('.feed-icon').find('a').html('<i class="fa fa-arrow-circle-down"></i> Download Comparison (CSV)');
	  }
}

$('.content').bind("DOMSubtreeModified",changeIconToText);

$(function(){
	changeIconToText();
});
ogomez78’s picture

You can use css to remove the image using 'display: none' and use the pseudo elements :before and/or :after to style the button further and add 'text' to it using something like this:

&:before {
content: "Download Results";
width: 150px;
line-height: 30px;
}

andileco’s picture

Don't know why I didn't think of that--that is a lot easier...thanks for sharing, @ogomez78!

I would still like to reiterate that it would be nicer if the module had a checkbox in the view format settings section where one could select text, and then input the text they would like to have appear. There's already a place to add the link title.

RogerRogers’s picture

Just to chime in that I'd really like to see this feature. The module is great. Having the ability to use simple text for the link would make theming considerably easier. The feed icons are too small/lack descriptive information in many cases.

Exploratus’s picture

Agreed.

andileco’s picture

This patch takes a slightly different approach from @zubher's (comment #5). It adds two new fields into the "Settings" modal. The first is a checkbox for (when selected) providing the download link as a text link instead of an icon/image link. The second field is a textfield for adding a class to the link, so that you can give the link a class like "button" (see picture) to your text link. I think this could help address this issue: https://www.drupal.org/node/1379672

andileco’s picture

The patch in #23 also suffers from the issue identified in #8. Somehow, $query needs to be added at the end of the path. Will keep looking for a solution.

andileco’s picture

OK, let's try this one.

andileco’s picture

Status: Needs work » Needs review
FileSize
3.42 KB

Last one for now--this works with the query and is written in a more Drupal-appropriate way--thanks for bearing with me for the last couple uploads--I'm learning PHP as I go.

joshuautley’s picture

Tested #26 and it works great! Thank you @andile2012

andileco’s picture

Thanks, @joshuautley! Do you feel we can change the status in the Issue Metadata to "Reviewed & tested by the community"?

joshuautley’s picture

I'd give it a couple days to see if anyone else chimes in. If not then sure give it a go.

andileco’s picture

Sounds good. By the way, there is a related issue: https://www.drupal.org/node/1379672. I think this option may be preferable, as it allows you to chose a text or image link at the same location as where you can change the alt text. In the other option, you have to visit two settings.

junestag’s picture

This patch (#26) worked perfectly for me, thank you!

jedsaet’s picture

#26 works great. +1 RTBC.

spazfox’s picture

#26 is not working for me. The text link and classes are applied fine, but the URL of the download link is not correct. For example, the correct link should be "myview/argument2value/csv," but instead the patch is generating "myview/%25/%25/csv"

Is this happening because I have an argument in the path? Is this patch working for anyone else using a view with an argument in the path? This issue may be relevant: #2275119: views::get_url() works incorrectly when there is an argument in the path

andileco’s picture

FileSize
3.39 KB

Great catch, @spazfox. This might fix. Please test!

spazfox’s picture

That did it! The patch (#34) is now working perfectly for me. Thanks for the quick fix, andile2012!

Kgaut’s picture

Working good thanks.

RTBC in my opinion.

milos.kroulik’s picture

The patch for #34 works fine from me, but GIT detected some white-space issues.

andileco’s picture

Thanks for catching, @milos.kroulik--I'll fix those errors.

andileco’s picture

OK, I think I fixed the whitespace errors with this one.

Steven Jones’s picture

Status: Needs review » Closed (duplicate)

I prefer the approach and patch in #1379672: Export Button, make it styleable with CSS so closing this issue as a duplicate, thanks for all the work, let's continue over there.

goldin’s picture

I prefer andile2012's approach. Intuitive and works like a charm. (I still got Git errors.) Thanks andile2012!

odizle’s picture

FileSize
23.61 KB

Hi Guys,

I'm posting this as a workaround for anyone that is looking to theme the button.
I was looking for a way to theme the button and used the solution offered in 12 just without the jQuery, using only CSS with FontAwesome.

The result looks like this:
css styled button

I added another class to the div surrounding the export link called "export-button"
(from
12)

<?php if ($exposed): ?>
    <div class="view-filters">
     <?php if(isset($view->feed_icon)): ?>
        <div class="feed-icon-wrapper export-button">
          <?php print $view->feed_icon; ?>
        </div>
      <?php endif; ?>
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

In my CSS I used the following:

.export-button a {
    padding: 15px 35px 15px 35px;
    display: -webkit-inline-box;
    background: #2295f3;
    color: white;
    text-align: center;
}
.export-button a:hover {
    box-shadow: 0 2px 6px rgba(0,0,0,.3);
}
.export-button img {
	display:none;
}
.export-button a:before {
    content: "Download CSV";
	color:white;
}
.export-button a:after {
	content: "\f019";
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-size: 15px;
    color: white;
    margin-left: 8px;
}

Please note, to use font awesome in the CSS you need to declare it in your CSS file.

@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.0.3');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

I hope this helps.

Amir Simantov’s picture

Styling different displays - e.g., CSV and TXT

What if you have displays to export by more than one extension type? In this case you need to add a different css content.

I took the idea of #19 and it goes as follows. I bet you can come with a more elegant code, but it worked for me:

<?php if ($feed_icon): ?>
  <div 
    <?php 
      $matches = array();
      
      // "all" because we may have more than one button, e.g., one for csv and one for txt
      preg_match_all( '/src="([^"]*)"/i', $feed_icon, $matches );

      // $matches[0] returns values with the attribure name, e.g., src="[DOMAIN]/sites/all/modules/views_data_export/images/csv.png"
      // if you want only the value of src then take values in $matches[1]

      $src_expressions = $matches[0];
      $class_expressions = array();

      // The strings 'csv.png' and 'txt.png' are part of the hard coded images in the module
      foreach ($src_expressions as $index => $value) {
        if (strpos($value, 'csv.png') !== false){
          $href_pos = strpos($feed_icon, '<a href') + 3; // 3 characters: '<a '
          $feed_icon = substr_replace($feed_icon, 'class="custom-csv"', $href_pos, 0);
        }
        if (strpos($value, 'txt.png') !== false){
          $href_pos = strpos($feed_icon, '<a href') + 3; // 3 characters: '<a '            
          $feed_icon = substr_replace($feed_icon, 'class="custom-txt"', $href_pos, 0);
        }
      }

      print 'class="feed-icon">';
    ?>
    <?php print $feed_icon; ?>
  </div>
<?php endif; ?>

Saas:

.feed-icon{

	a{

		&.custom-csv::after{
			content: 'Export as CSV';
		}
	
		&.custom-txt::after{
			content: 'Export as TXT';
		}	
		
		img{
			display: none;
		}			
	}
}