make a link holding a model - javascript

I have a string Data in my model that can be pretty long. I'm trying to take the first 150 chars and then make it clickable, and when the link is clicked a new div should appear with the whole message. Below am I using tag, but I dont know how to give it a unique ID and make it store my item.Data.
Can someone help me with some ideas?
#foreach (var item in Model) {
<div class="row">
<div class="col-md-1">
#Html.DisplayFor(modelItem => item.Level)
</div>
<div class="col-md-2">
#Html.DisplayFor(modelItem => item.Source)
</div>
<div class="col-md-1">
#Html.DisplayFor(modelItem => item.Date)
</div>
<div class="col-md-5">
<a ID="?">#Html.DisplayFor(modelItem => item.Data).ToString().Substring(0, 150) ...</a>
</div>
<div class="col-md-1">
#Html.DisplayFor(modelItem => item.Count)
</div>
</div>
}

Essentially, you'll just need something like this:
<a class="show-data" href="#AllData">
#item.Data.Substring(0, 150)
</a>
<div id="#AllData" style="display:none">
#item.Data
</div>
Then, a bit of JS:
$('.show-data').on('click', function () {
$($(this).attr('href')).toggle();
});
Take note, though, for simplicity of the example, I just assigned the div an id of AllData. Since this is inside a foreach loop, you'll need to use something to make each id unique. This could be the id of the item or you could use a for loop instead of foreach, and then use the index. Just be sure to make the href of the link and the id of the div match and be unique for the page.

#Html.DisplayFor(modelItem => item.Data).ToString().Substring(0, 150)

Related

Javascript - Use array values dynamically in HTML

My end result is supposed to be a list of objects in html. Bootstrap behind this. I'd like for the list to be created dynamically so I don't have to manually create all the divs because I don't know how many there will be. Here's what I have.
I have an array similar to this:
activities =
[
{
"activityOwner": "Raymond Carlson",
"activityDesc": "Complete all the steps from Getting Started wizard"
},
{
"activityOwner": "Flopsy McDoogal",
"activityDesc": "Called interested in March fundraising Sponsorship"
},
{
"activityOwner": "Gary Busy",
"activityDesc": "Get approval for price quote"
}
]
This is the first part where I'm not sure what to do. I can assign the element ids individually for my html like this but what I'd like to do is count how many elements are in my array and create these for me. I won't know how many there are to make these manually. I'm sure there needs to be a loop but I couldn't figure it out.
document.getElementById('activityowner0').innerHTML = activities[0].activityOwner;
document.getElementById('activitydesc0').innerHTML = activities[0].activityDesc;
document.getElementById('activityowner1').innerHTML = activities[1].activityOwner;
document.getElementById('activitydesc1').innerHTML = activities[1].activityDesc;
document.getElementById('activityowner2').innerHTML = activities[2].activityOwner;
document.getElementById('activitydesc2').innerHTML = activities[2].activityDesc;
etc.
etc.
And then...once I have that part, I'd like to know how to create my html divs dynamically based on how many elements are in my array. Again, right now I don't know how many there are so I'm having to create a bunch of these and then have extras if I have too many.
<div class="container">
<div class="row"></div>
<div class="qa-message-list" id="wallmessages">
<br>
<div class="message-item" id="m0">
<div class="message-inner">
<div class="message-head clearfix">
<div class="user-detail">
<h5 class="handle">
<p id='activityowner0'></p>
</h5>
<div class="post-meta"></div>
</div>
</div>
<div class="qa-message-content">
<p id='activitydesc0'></p>
</div>
</div>
</div>
I know this is a big ask so just pointing me in the right direction would be very helpful. I hope my question was clear and I appreciate it.
One way for you to achieve this would be to loop through the objects in your activities array. From there you can use a HTML template to store the base HTML structure which you can clone and update with the values of each object before you append it to the DOM.
In addition, an important thing to note when generating repeated content in a loop: never use id attributes. You will either end up with duplicates, which is invalid as id need to be unique, or you'll end up with ugly code generating incremental/random id at runtime which is unnecessary. Use classes instead.
Here's a working example:
const activities = [{ "activityOwner": "Raymond Carlson", "activityDesc": "Complete all the steps from Getting Started wizard"}, {"activityOwner": "Flopsy McDoogal","activityDesc": "Called interested in March fundraising Sponsorship" }, { "activityOwner": "Gary Busy", "activityDesc": "Get approval for price quote" }]
const html = activities.map(obj => {
let item = document.querySelector('#template').innerHTML;
item = item.replace('{owner}', obj.activityOwner);
item = item.replace('{desc}', obj.activityDesc);
return item;
});
document.querySelector('#list').innerHTML = html.join('');
<div id="list"></div>
<template id="template">
<div class="container">
<div class="row"></div>
<div class="qa-message-list">
<div class="message-item">
<div class="message-inner">
<div class="message-head clearfix">
<div class="user-detail">
<h5 class="handle">
<p class="activityowner">{owner}</p>
</h5>
<div class="post-meta"></div>
</div>
</div>
<div class="qa-message-content">
<p class="activitydesc">{desc}</p>
</div>
</div>
</div>
</div>
</div>
</template>

How to pass value to modal using React.js?

I have a table that returns data after a .data.map().. as shown below:
{this.state.data.map((item, i) => {
return (div>
<tr>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.symbol}</td>
And a <td> in the same <table> and <tr> above that displays my modal with the below code:
<td>
<div>
<a className="btn" href="#open-modal" title="More Details">👁</a>
<div id="open-modal" className="modal-window">
<div>
❌
<div>Update Details</div>
<label>{item.id}</label> //WHERE I WANT TO DISPLAY MY ID
</div><a href={url}></a></div>
</div>
</td>
Now when I want to display the item.id of each particular row after opening the modal, it returns the item.id of only 1 item in the array and not the actual item.id.
So the item.id in <td> is different from the item.id in the modal. It keeps returning the same item.id for every row I click on. How can I have these 2 have the same value?
The modal only reference to your last id at the time you rendered it
I would suggest you have a state to store your id and render it when you open your modal.
Something like:
const [selectedId, setSelectedId] = useState();
<td>
<div>
<a
className="btn"
onClick={() => setSelectedId(item.id)}
href="#open-modal" title="More Details"
>👁</a>
<div id="open-modal" className="modal-window">
<div>
❌
<div>Update Details</div>
<label>{selectedId}</label>
</div><a href={url}></a></div>
</div>
</td>
The 👁 looks scary though.

Calling the id of a div where the id looks like id=#something

<div class="external-event bg-red-gradient text-center" style="position: relative;">
<div id="#wo.id" class="WoOrders">
#Html.DisplayFor(modelItem => wo.id) --
#Html.DisplayFor(modelItem => wo.warehouse_number) --
#Html.DisplayFor(modelItem => wo.warehouse_order_number) --
#Html.DisplayFor(modelItem => wo.warehouse_process_type) --
#Html.DisplayFor(modelItem => qu.QueueId)
</div>
</div>
How could i call the id of that div-element (i've tried getElementById() without success).
Thanks in advance.
(Newbie :))
This is server-side code in ASP.NET:
#wo.id
It's not what gets rendered to the actual client-side. That would be whatever the value of wo.id is. So, for example, if the value is "someIdentifier" then you'd have this:
<div id="someIdentifier" class="WoOrders">
In which case you'd identify that element in JavaScript with:
var element = document.getElementById('someIdentifier');
You need to escape the # symbol with '\#wo.id' in your call.
https://jsfiddle.net/mw864znm/
document.getElementById('\#test').className= "red";

delete the current <tr> and also delete the <tr> before it using plain javascript

I have this HTML structure:
<tr class="project-details">REMOVE THIS</tr>
<tr class="project-description">
<td colspan="6">
<div class="project-desc-inner">
<div class="project-synopsis">
<p class="trunk8">This is an entry</p>
</div>
<div class="project-verification">
<span class="verfied-badge"> <~~~~~~~~~~ THIS SPAN
<span class="currency-symbol">$</span>
<span class="icon-tick"></span>
Verified
</span>
</div>
<div class="project-actions">
<a href="#">
<button class="btn">LOL</button>
</a>
</div>
</div>
</td>
</tr>
And I hope that the entire <tr class="project-details">REMOVE THIS</tr> plus its contents will be remove completely
This is what I have so far:
function showAlert()
{
var projectDescriptions = document.querySelectorAll('tr.project-description'),
projectDescriptions = Array.prototype.slice.call(projectDescriptions);
projectDescriptions.forEach(function(el) {
if (el.querySelector('span.verfied-badge')) {
}else {
el.parentNode.removeChild(el);
el.prev('tr').remove();
}
});
}
What it does is select the <tr> with the <span> I am looking for, then delete the entire span. This part el.prev('tr').remove(); is not working, any alternative?
Thanks!
The body of the else clause:
(function removePreviousSibling(sibling) {
if (sibling.nodeName === 'TR' && sibling.classList.contains('project-details')) {
return sibling.parentNode.removeChild(sibling);
}
removePreviousSibling(sibling.previousSibling);
}(el.previousSibling));
el.parentNode.removeChild(el);
The IIFE ensures if there is an extra text node between the two <tr> elements that the text node will be skipped and not deleted if you just did called a removeChild on the previousSibling of the target element.
Take a look over the information at MDN's DOM page. It's got a great set of interface documentation and tutorials.
prev is a method of a jQuery object. HTMLElement object has no prev method. For selecting the previous element sibling you can use the previousElementSibling property.

Adding multiple partial views and first one is missing form

I have the following:
_ImageGalleryPartial
#if (Model != null)
{
foreach (var item in Model)
{
#Html.Partial("_ImageItem", item);
}
}
_ImageItemPartial
#model WebsiteEngine.Models.PortfolioImage
#{
string url = VirtualPathUtility.ToAbsolute(String.Format("~/{0}", Html.DisplayFor(m => m.FileName)));
}
#using (Html.BeginForm("DeleteImage", "Portfolio", FormMethod.Post, new { #class = "deleteImageForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true);
#Html.HiddenFor(m => m.Name)
#Html.HiddenFor(m => m.FileName)
#Html.HiddenFor(m => m.Order)
#Html.HiddenFor(m => m.PortfolioID)
#Html.HiddenFor(m => m.PortfolioImageID)
<div class="span3">
<div class="item">
<a class="fancybox-button" data-rel="fancybox-button" title="Photo" href="#url">
<div class="zoom">
<img src="#url" alt="Photo" />
<div class="zoom-icon"></div>
</div>
</a>
<div class="details">
<i class="icon-remove"></i>
</div>
</div>
</div>
}
When I inspect the page elements using Chrome dev tools, the first element is missing the surrounding form. If I inspect the page source (using right) click then the form is there. This lead me to believe some JS was removing the form so I disabled JS but it was still missing.
If change _ImageGalleryPartial so it's like this (notice the addition of an empty model):
#if (Model != null)
{
#Html.Partial("_ImageItem", new WebsiteEngine.Models.PortfolioImage());
foreach (var item in Model)
{
#Html.Partial("_ImageItem", item);
}
}
Then all the "correct" elements get a form but again, this first item doesn't.
I'm still inclined to think this is a JS issue but I'm a little stumped as disabling JS doesn't fix it. Is this some off behaviour with MVC?
Just to note, I have simplified my layout above, I do actually have one or 2 nested forms but assume that's Ok as everything else is Ok, it's just this first partial that's broken.
Any ideas?
Html forms can't be nested.
Chrome will ignore illegal tags, thus they are not showing.
You can read this post for further information.

Categories

Resources