{"action":"created","issue":{"url":"https://api.github.com/repos/bokeh/bokeh/issues/4207","repository_url":"https://api.github.com/repos/bokeh/bokeh","labels_url":"https://api.github.com/repos/bokeh/bokeh/issues/4207/labels{/name}","comments_url":"https://api.github.com/repos/bokeh/bokeh/issues/4207/comments","events_url":"https://api.github.com/repos/bokeh/bokeh/issues/4207/events","html_url":"https://github.com/bokeh/bokeh/pull/4207","id":149975094,"number":4207,"title":"adds server app example for exporting ColumnDataSource data to csv","user":{"login":"jbrambleDC","id":6984748,"avatar_url":"https://avatars.githubusercontent.com/u/6984748?v=3","gravatar_id":"","url":"https://api.github.com/users/jbrambleDC","html_url":"https://github.com/jbrambleDC","followers_url":"https://api.github.com/users/jbrambleDC/followers","following_url":"https://api.github.com/users/jbrambleDC/following{/other_user}","gists_url":"https://api.github.com/users/jbrambleDC/gists{/gist_id}","starred_url":"https://api.github.com/users/jbrambleDC/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbrambleDC/subscriptions","organizations_url":"https://api.github.com/users/jbrambleDC/orgs","repos_url":"https://api.github.com/users/jbrambleDC/repos","events_url":"https://api.github.com/users/jbrambleDC/events{/privacy}","received_events_url":"https://api.github.com/users/jbrambleDC/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/bokeh/bokeh/labels/status:%20WIP","name":"status: WIP","color":"fef2c0"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2016-04-21T05:59:08Z","updated_at":"2016-04-29T15:08:59Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/bokeh/bokeh/pulls/4207","html_url":"https://github.com/bokeh/bokeh/pull/4207","diff_url":"https://github.com/bokeh/bokeh/pull/4207.diff","patch_url":"https://github.com/bokeh/bokeh/pull/4207.patch"},"body":"Opening this PR at the reccomendation of @bryevdv . This addresses #4206 . This is a simple bokeh server app that can be ran with `bokeh serve --show csv_export.py`. Upon launching the app you will see a data table render. The sliders allow one to change the max salary of this data. The download button is configured with a CustomJS callback to export the data to csv in the users browser.  I suspect we do not need to tests given that this is an example server app and not a a feature being added to the Bokeh library.\r\n\r\nI have currently only tested this on chrome. It should work on Firefox and IE as well. \r\n\r\nNOTE: this is my first PR to bokeh, so please bear with me. \r\n\r\nAlso, I completely understand if we want to avoid allowing people to add their own sample data .csvs to this repo in Pull Requests. It could pollute the repo. We can discuss using some of the Bokeh sample data to accomplish this same task if needed. \r\n\r\nthe customJS is defined as follows:\r\n\r\n```python\r\njs_callback = \"\"\"\r\nvar data = source.get('data');\r\nvar filetext = 'name,income,years_experience\\\\n';\r\nfor (i=0; i < data['name'].length; i++) {\r\n    var currRow = [data['name'][i].toString(),\r\n                   data['salary'][i].toString(),\r\n                   data['years_experience'][i].toString().concat('\\\\n')];\r\n\r\n    var joined = currRow.join();\r\n    filetext = filetext.concat(joined);\r\n}\r\n\r\nvar filename = 'data_result.csv';\r\nvar blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' });\r\n\r\n//addresses IE\r\nif (navigator.msSaveBlob) {\r\n    navigator.msSaveBlob(blob, filename);\r\n}\r\n\r\nelse {\r\n    var link = document.createElement(\"a\");\r\n    if (link.download !== undefined) {\r\n        var url = URL.createObjectURL(blob);\r\n        link.setAttribute(\"href\", url);\r\n        link.setAttribute(\"download\", filename);\r\n        link.style.visibility = 'hidden';\r\n        document.body.appendChild(link);\r\n        link.click();\r\n        document.body.removeChild(link);\r\n    }       \r\n}\"\"\"\r\n\r\nbutton.callback = CustomJS(args=dict(source=source), code=js_callback)\r\n```"},"comment":{"url":"https://api.github.com/repos/bokeh/bokeh/issues/comments/215747654","html_url":"https://github.com/bokeh/bokeh/pull/4207#issuecomment-215747654","issue_url":"https://api.github.com/repos/bokeh/bokeh/issues/4207","id":215747654,"user":{"login":"jbrambleDC","id":6984748,"avatar_url":"https://avatars.githubusercontent.com/u/6984748?v=3","gravatar_id":"","url":"https://api.github.com/users/jbrambleDC","html_url":"https://github.com/jbrambleDC","followers_url":"https://api.github.com/users/jbrambleDC/followers","following_url":"https://api.github.com/users/jbrambleDC/following{/other_user}","gists_url":"https://api.github.com/users/jbrambleDC/gists{/gist_id}","starred_url":"https://api.github.com/users/jbrambleDC/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbrambleDC/subscriptions","organizations_url":"https://api.github.com/users/jbrambleDC/orgs","repos_url":"https://api.github.com/users/jbrambleDC/repos","events_url":"https://api.github.com/users/jbrambleDC/events{/privacy}","received_events_url":"https://api.github.com/users/jbrambleDC/received_events","type":"User","site_admin":false},"created_at":"2016-04-29T15:08:59Z","updated_at":"2016-04-29T15:08:59Z","body":"@bryevdv I think everything is good to go here. Unless you want to do something further to address the Safari issue. Im going to punt on the PyScript implementation for now. I think it will be good however, eventually to show people how to do these kind of document interactions with JS callbacks and Python implementations.\r\n\r\nLet me know if you need anything before merge!"}}