I display the list of files, (in a database), that I could download in a table.
<table style="border: none; width:100%">
#for (int i = 0; i <= Model.docs.Count() - 1; i++)
{
<tr onclick="downloadFile('#Model.docs[i].id.ToString()')" class="rowFile" data-row=#i id=#("rigaDoc" + i)>
<td style="border-bottom:1px solid black; width:30px;">
<img src="#Url.Content(Model.docs[i].icon)" alt="Image" />
</td>
<td style="border-bottom:1px solid black; padding-left: 20px; width:auto;">
#Html.Label(Model.docs[i].nameFile.ToString().Split('.')[0], new { #class = "" })
</td>
</tr>
}
</table>
Once the user clicks on a row of that table, I need to send to the controller the GUID of that row and start the file download.
function downloadFile(fileId) {
var urlDownload = '#Url.Action("Download", "GestioneDocumenti", new { id = fileId })';
}
However, I cannot use fileId because debugger says:
"the name fileId is not used in this context".
How can I send the information to the controller method?
Razor is server side code and is parsed on the server before it is sent to the view. Change your function to
function downloadFile(fileId) {
var urlDownload = '#Url.Action("Download", "GestioneDocumenti")' + '/' + fileId;
}
A better solution would be to generate the url as a data- attribute
<tr data-url="#Url.Action("Download", "GestioneDocumenti", new { id = Model.docs[i].id })" class="rowFile">
and change the script to
$('.rowFile').click(function() {
var urlDownload = $(this).data('url');
});
Related
I would like to convert every message that is received into an image, and with the download button download it. every post is different
This is my .js code
// fetch Messages
function fetchData() {
$('#displayMessages').html('<div class="alert alert-info">Stiamo recuperando i tuoi messaggi!...</div>');
$('#messages').click();
$.ajax({
url: 'controller/fetch_comments.php',
//success
success: function(data){
if (data=='please login') {
window.location='./';
console.log(data);
}
else{
var $fetch ='';
var component ='';
if (/^[\],:{}\s]*$/.test(data.replace(/\\["\\\/bfnrtu]/g, '#').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
data=JSON.parse(data);
console.log(data);
$.each(data, function(i, fetchAll){
var fetchData= data[i];
let message_title = fetchData.message_title ?? ""
$fetch += '<div class="row m-0"> <div class="pull-left alert col-md-2 mb-0"><img src="assets/img/anon.jpg" style=" width: 50px; height: 50px; border-radius:50%; box-shadow: 0 3px 2px rgba(0, 0, 0, 0.3); border: 5px solid #2c2c2c;" class="m-0"></div> <div class="alert col-md-7 m-0" style="margin-left:0px; color:#2c2c2c;"> <b>' +message_title +'</b><br>' +fetchData.description
+'</div> <div class="col-md-3 alert pull-right m-0"><span style="color: black;" class="fa fa-clock m-0"></span><br><text style="color: black; font-size:10px;"> ';
$fetch+=fetchData.date_created+'</text></div></div>';
});
} else {
$fetch +='<div class="alert alert-danger">Ancora nessun messaggio 😒</div>';
console.log(fetch);
$('#displayMessages').html($fetch)
}
$('#displayMessages').html($fetch);
}
}
});
}
this is the php code
$usersObj = new Comments();
$logsObj = new Logs();
$id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 1;
if (empty($id)) {
exit();
}
if ($allComments = $usersObj ->FETCH_COMMENTS($id)) {
$logDescription = 'data fetched!';
$logsObj->INSERT_LOG($id, $logDescription);
}else{
echo 'log failed';
}
echo isset($allComments) ? json_encode($allComments) : 'nothing found';
This is my html in my dashboard, is used to show the message
<div class="tab-pane active" id="home" role="tabpanel">
<div id="displayMessages">
</div>
</div>
I don't understand where I have to act, thanks for the help feel free to edit the code
You could do this as a oneliner in javascript.
Just by using the library html2canvas.
e.g.
html:
<div id="capture" style="padding: 10px; background: #f5da55">
<h4 style="color: #000; ">Hello world!</h4>
</div>
js:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
put the image into an a tag with the propertie of "download".
I hope i could help you out.
EDIT:
In your html file add the cdn as following to the head:
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas
/1.4.1/html2canvas.min.js"></script>
then in your js file
const body = document.querySelector("body");
const a_tag = document.createElement("a"); //just create an a tag
a_tag.innerHTML = "download"; //this text is displayed
a_tag.download = "image.png"; //pictures will download as image.png - you can customize the name and file format, but not all formats are acceptet in html2canvas
body.appendChild(a_tag); //append the a tag to the body element, you will need to customize this for your needs
html2canvas(document.querySelector(".wrapper")).then((canvas) => {
canvas.toBlob((blob) => {
const url = URL.createObjectURL(blob); //creates location of image
a_tag.href = url; //append url to a tags href
});
});
You will need this for every Message you receive. After your messages are displayed in the dom as html, the "html2canvas" will create an image out of that. In the "toBlob" function the image is just cached but not showing anywhere. We link the blob url (location of the cached image) to the a tags href. So if we then click on it, it will download. The .wrapper in the html2canvas function i've selected should be your message-div
I have this JSON from which I need to create a table. This table must be a legend for a webmap created with OpenLayers 6. As you have seen the JSON comes from Geoserver.
Below my code:
let updateLegend = function(resolution) {
let graphicUrl = strutturale_puc.getSource().getLegendUrl(
resolution,
{'FORMAT': 'application/json'}
);
if(graphicUrl) {
fetch(graphicUrl)
.then(function (response) {
return response.text();
})
.then(function (data) {
const jsonData = JSON.parse(data);
const legendData = jsonData.Legend[0].rules;
const table = document.getElementById("table");
const footer = table.createTFoot();
legendData.forEach((value) => {
cellStroke = value.symbolizers[0].Polygon.stroke;
cellFill = value.symbolizers[0].Polygon.fill;
cellContent = value.name;
const tableRaw = footer.insertRow(value);
tableRaw.insertCell(0).innerHTML = '<td style="border: 4px solid ' + cellStroke + '; background-color: ' + cellFill + '; max-width: 10px;"></td>';
tableRaw.insertCell(1).innerHTML = '<td style="border: none;">' + cellContent + '</td>';
console.log(tableRaw);
});
}).catch((error) => {
console.error(error)
});
}
The table is inside a div:
<div class="" id="legend">
<table class="table" id="table">
</table>
</div>
My problem is that I can't see any style when the table is created, I can see only the text(cellContent). For me is strange because if I use this:
<div class="">
<table>
<tr>
<td style="border: 4px solid #791919; background-color: #A71C1C; max-width: 10px;"></td>
<td style="border: none;">Item</td>
</tr>
</table>
</div>
I can see all correctly. What I wrong?
.insertCell creates a <td> element, inserts it into the table, and returns a reference to it (per the spec).
You then set the contents of that <td> to contain another <td> where you add the styling rule.
So now you essentially have:
<td>
<td style="border: 4px solid #791919; background-color: #A71C1C; max-width: 10px;"></td>
</td>
You can only have a <td> tag within a <tr> tag, so the browser removes the internal <td> tag (along with its styling), and adds its contents to the original <td>.
To solve the issue, you need to add the styling to the <td> that it makes for you. For example:
let firstCell = tableRaw.insertCell(0);
firstCell.setAttribute("style", 'border: 4px solid ' + cellStroke + '; background-color: ' + cellFill + '; max-width: 10px;');
firstCell.innerHTML = "";
Code quality notes:
You should use CSS classes rather that inline styles.
You should use template literals rather than inline string concatenation.
I have jsp page where I get products from database and for each product i have several images. i want to create simple image slider in JS for each product, but i can't get an array of images on JS. i try to do it by id in img tag, but have null. i understand that i need to use JQuery and i need to get a link on every product img, but don't know how, maybe somebody can help me.
Jsp
<c:forEach items="${produkt}" var="produkt">
<div class="produkt-container" style=" border: 1px solid #ccc; display: inline-block;text-align:left;">
<a href="produkt${produkt.id}" >${produkt.model}</a>
<%--<img src="${produkt.images[o]}" alt="">--%>
<div id="img-container" style="max-width: 280px">
<button class="btnClass" id="prev" onclick="plusImg(-1)">❮
</button>
<c:forEach items="${produkt.images}" var="image">
<img src="${image}" id="img-list" alt="" style="border: 1px solid black; width: 260px">
</c:forEach>
<button class="btnClass" id="next" onclick="plusImg(1)">❯</button>
</div>
</div>
</c:forEach>
simple slider in js
<script>
var count = 1;
sliderImg(count);
function plusImg(n) {
sliderImg(count += n);
}
function sliderImg (n) {
var i;
// var ar = $('.produkt-container').find('a');
// var x = $(this).attr('href');
var x = document.getElementsByClassName(".img-list");
if(n > x.length){count =1}
if(n < 1){count = x.length}
for (i =0; i<x.length; i++){
x[i].style.display ="none";
}
x[count-1].style.display = "block";
console.log(x);
}
Scenario:
I have a results table with a checkbox, when the checkbox is checked, the content of the row(actually 2 columns concateneted only, are copied to a new div, with the job code and job name). This works pretty well, and I am avoiding duplicated already.
However, in the new results div, I am creating an anchor tag to remove the div itself.
After the div has been removed, I should be able to add the selected job again with the checkbox.
Please note that there are many jobs in the results table, so putting the flag to false again will not work.
Also if you find a better title for this question, please let me know
//On every checkbow that is clicked
var flag = false;
$("#ctl00_PlaceHolderMain_myGrid input").change(function () {
if (this.checked && flag === false) {
flag = true;
var jobCode = $(this).parent().parent().parent().find("td:eq(2)").text()
var jobName = $(this).parent().parent().parent().find("td:eq(1)").text()
var displayvalue = jobCode.toUpperCase() + " - " + jobName.toUpperCase();
AddSelectedJob(jobCode, displayvalue);
//$(this).unbind('change'); //Unbind the change event so that it doesnt fire again
FillSelectedJobs();
}
});
//Add selected job in the results div
function AddSelectedJob(id, display) {
//create a div for every selected job
$("[id$=ResultsDiv]").append('<div class="selectedjobs" id=' + id + '>' + display + 'Remove selected job</div>');
}
//Removes the selected job from the resutls div
function removeSelectedJob(el) {
$(el).parent().remove();
}
The generated html is like this:
<div>
<div style="height: 300px; overflow: auto; float: left">
<div>
<table cellspacing="0" cellpadding="4" id="ctl00_PlaceHolderMain_myGrid" style="color:#333333;width:100%;border-collapse:collapse;">
<tr style="color:White;background-color:#5D7B9D;font-weight:bold;">
<th scope="col"> </th><th scope="col">JobCode</th><th scope="col">JobName</th><th scope="col">JobPartner</th><th scope="col">JobManager</th><th scope="col">ClientName</th>
</tr><tr style="color:#333333;background-color:#F7F6F3;">
<td>
<input id="ctl00_PlaceHolderMain_myGrid_ctl02_CheckBox1" type="checkbox" name="ctl00$PlaceHolderMain$myGrid$ctl02$CheckBox1" />
</td><td>jobcode01</td><td>jobname</td><td>xx</td><td>xx</td><td>xx</td>
</tr>
</table>
</div>
</div>
<div style="margin-top: 0px; margin-left: 10px; float: left">
<span>Selected :</span>
<div id="ResultsDiv" style="margin-top: 0px">
</div>
</div>
Firstly I suggest some changes to your HTML. Separate out the styles from your DOM and place them in classes.
This makes sure there is separation of concerns
HTML
<div>
<div class="divMain">
<div>
<table cellspacing="0" cellpadding="4"
id="ctl00_PlaceHolderMain_myGrid" class="table">
<tr class="rowHead">
<th scope="col"> </th>
<th scope="col">JobCode</th>
<th scope="col">JobName</th>
<th scope="col">JobPartner</th>
<th scope="col">JobManager</th>
<th scope="col">ClientName</th>
</tr>
<tr class="row">
<td>
<input id="ctl00_PlaceHolderMain_myGrid_ctl02_CheckBox1"
type="checkbox"
name="ctl00$PlaceHolderMain$myGrid$ctl02$CheckBox1"
data-flag="false" />
</td>
<td>column1</td>
<td>column2</td>
<td>column3</td>
<td>column4</td>
<td>column5</td>
</tr>
</table>
</div>
</div>
<div class="m0 selected">
<span>Selected :</span>
<div id="ResultsDiv" class="m0"></div>
</div>
CSS
.divMain{
height: 300px;
overflow: auto;
float: left
}
.table{
color:#333333;
width:100%;
border-collapse:collapse;
}
.rowHead{
color:White;
background-color:#5D7B9D;
font-weight:bold;
}
.row{
color:#333333;
background-color:#F7F6F3;
}
.m0{
margin-top: 0px;
}
.selected{
margin-left: 10px;
float: left
}
Javascript
$("#ctl00_PlaceHolderMain_myGrid input").change(function () {
// Next cache your selector
// so that you need not crawl the DOM multiple times
var $this = $(this),
$row = $this.closest('.row'),
currFlag = Boolean($this.data('flag'));
// As there might be multiple jobs , a single flag variable
// will not work. So you can set a data-flag attribute on the
// input that stores the current value
if (currFlag === false && this.checked) {
// Set the corresponding flag to true
$this.data('flag', true);
var jobCode = $row.find("td:eq(2)").text(),
jobName = $row.find("td:eq(1)").text(),
displayvalue = jobCode.toUpperCase() + " - "
+ jobName.toUpperCase(),
inputId = $this.attr('id')
// Pass the input name too as you need to set the value of
// the corresponding flag value again as you can add it multiple times
AddSelectedJob(jobCode, displayvalue, inputId);
FillSelectedJobs();
}
});
//Add selected job in the results div
function AddSelectedJob(id, display, inputId) {
//create a div for every selected job
// Use the inputId to save it as a data-id attribute
// on anchor so that you can set the value of the flag after
// removing it
var html = '<div class="selectedjobs" id=' + id + '>' + display ;
html += '<a href="javascript" data-id="'+ inputId
+'">Remove selected job</a></div>';
$('[id$=ResultsDiv]').append(html);
}
// Remove the inline click event for the anchor and delgate it to the
// static parent container
$('[id$=ResultsDiv]').on('click', 'a', function(e) {
var $this = $(this),
$currentCheckbox = $this.data('id');
// Set the flag value of the input back to false
$('#'+ $currentCheckbox).data('flag', false);
e.preventDefault(); // prevent the default action of the anchor
$this.closest('.selectedjobs').remove();
});
function FillSelectedJobs() {
//save values into the hidden field
var selectedJobs = $("[id$=ResultsDiv]").find("[class$='selectedjobs']");
var returnvalue = "";
for (var i = 0; i < selectedJobs.length; i++)
returnvalue += selectedJobs[i].id + ";";
$("[id$=HiddenClientCode]").val(returnvalue);
}
Check Fiddle
I got an HTML string as (var code); I want to extract all values of sid=(example:12345) inside href and title(example: Star Album) and episode number (example:episode 4) but i am wondering how I can do that in JavaScript and have all sid, title and episode number values in array so i can construct hyperlinks ?
Note: initial value of $code is blocks of div like example below:
<td width=120 valign="top"> <div style="height:135px;
border:1px solid #BBBBBB; background:#BBBBBB; margin-left:2px;
text-align:center; ">
<a href="/now/episodes.php?name=path&id=4000&sid=12345&page=0"><img
border="0" src="http://www.somesite.com/1234.jpg" width="150"
height="83"></a><br>
<font face="Tahoma" size="2"><b>Star Album</b><br/>
episode 4
</font> </div>
</td>
Hope this helps:
Demo
var code = '<td width=120 valign="top"><div style="height:135px;border:1px solid #BBBBBB; background:#BBBBBB; margin-left:2px;text-align:center;"><img border="0" src="http://www.somesite.com/1234.jpg" width="150" height="83"><br><font face="Tahoma" size="2"><b>Star Album</b><br/>episode 4</font></div></td>';
function getDetails(html){
var div = $('<div></div>')
div.html(html);
var count=0;
var arr = [];
div.find('a').each(function(){
var href = $(this).attr('href');
href = href.substring(href.indexOf('sid=')+4, href.indexOf('&page='));
var title = $(this).parent().find('b').eq(count++).text();
arr.push({"sid" : href , "title": title});
});
return arr;
}
console.log(getDetails(code));