فهرست
توی یه پروژه از من خواسته شد برای فرمهایی که با پاورفرم توی شیرپوینت ساخته شده قالبی برای نمای پرینت فرم طراحی کنم. یه سر به سایت رسمی سازنده پاورفرم زدم، اما نتیجهای نگرفتم و بعد از یک روز سروکله زدن، متوجه شدم پرینت کردن توی پاورفرم چطوری کار میکنه.
توی این پست بررسی میکنیم که چطوری میشه با استفاده از یه فایل XSLT، نمای مخصوصی برای پرینت فرم پاورفرم طراحی کرد و گام به گام نحوه پیادهسازی این قابلیت رو بررسی میکنیم؛ برای ایجاد این نمای مخصوص چاپ در فرمهای پاورفرم، مراحل زیر رو باید طی کنیم:
1. تنظیماتِ فرمِ پاورفرم
فرض من اینه که شما به طراحی فرم با پاورفرم مسلط هستید، یه خُرده HTML و CSS میدونید و قبلاً فرم مد نظرتونو توی پاورفرم طراحی کردید. بعد از تکمیل طراحی فرم، باید توی محیط ویرایشگر فرم پاورفرم، وارد بخش Options بشید و توی بخش General Settings، تیک Show Print Button رو فعال کنید:
برای این که پاورفرم، فرم رو برای پرینت آمادهسازی کنه، نیاز به یه فایل با فرمت XSLT داره. فایلهای XSLT فایلهایی هستن که به عنوان قالب (template) برای نمایش اطلاعات XML استفاده میشن؛ بنابراین لازمه که یه فایل با فرمت XSLT بسازید، با هر ویرایشگری که راحت هستید بازش کنید و این محتوا رو داخلش قرار بدید:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<table style="border: 2px das">
<xsl:for-each select="ListItem/Control">
<tr>
<td>
<xsl:value-of select="@ControlName"/>
</td>
<td>
<xsl:value-of select="@ControlType"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
این فایل XSLT رو ذخیره کنید و یه جایی توی یکی از مخزنهای شیرپوینت قرار بدید، به محیط طراحی پاورفرم برگردید و آدرس فایل آپلود شده رو توی تنظیمات فرم، توی بخش Printing و داخل فیلد XSLT file url وارد کنید:
تنظیمات فرم پاورفرم رو ذخیره کنید و صفحهای که فرم توش نمایش داده میشه رو رفرش کنید. میبینید که اکشنهای مرتبط با پرینت کردن فرم، بالای صفحه ظاهر میشن.
با کلیک روی دکمه پرینت صفحه جدیدی باز میشه که همه فیلدهای فرم توش نمایش داده میشه (اگه با کلیک کردن روی دکمه پرینت صفحه جدید باز نشد کنسول مرورگرو باز کنید و سعی کنید خطایی که موقع کلیک روی دکمه پرینت به وجود میادو برطرف کنید).
کدی که توی فایل XSLT نوشتید، در واقع یه لوپه که همه فیلدهای فرم رو توی نمای پرینت نمایش میده، اما در عمل احتمالاً موقع پرینت کردن فرم، نیاز به نمایش همه فیلدهای فرم ندارید یا فقط نیاز دارید تعداد کمی از فیدها رو نمایش بدید. در ادامه میبینیم که چطور میشه به صورت مشخص، فقط فیلدهایی که لازم داریمو توی نمای پرینت نمایش بدیم.
2. مشخص کردن فیلدها در فایل XSLT
مهمترین چیزی که توی فایل XSLT هست، بخش مربوط به نمایش دادههای فرمه. با استفاده از تگهای <xsl:value-of>
میتونید دادههایی که توی فرم دخیره شدن دریافت کنید و هر جایی که لازم هست نمایش بدید. مثلاً برای نمایش مقدار هر کدوم از فیلدها، میتونید از این سینتکس توی فایل XSLT استفاده کنید:
<tr>
<td colspan="1" class='heading'>عنوان فیلد</td>
<td colspan="3">
<xsl:value-of select="ListItem/Control[@ControlName='c_FieldName']"/>
</td>
</tr>
توی کد بالا باید نام فیلد موجود در فرم رو به جای c_FieldName
قرار بدید. نام فیلد رو باید از تنظیمات فیلد توی محیط ویرایش فرم پیدا کنید:
توی کد پایین چند تا فیلدی که برای نمایش توی نمای پرینت این فرم نیاز بوده را گذاشتم؛ دقت کنید که این مقادیر توی فرمهای مختلف متفاوتن و برای همین، برای هر فرم، نیاز به درست کردن یه فایل XSLT مخصوص نمای پرینت همون فرم هست (توی این مثال اسم فیلدها الکی هستن و شما باید اسم فیلدهای فرم خودتونو از توی محیط طراحی فرم پاورفرم پیدا کنید):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<table>
<tr>
<td colspan="1" class='heading'>فیلد اول</td>
<td colspan="3">
<xsl:value-of select="ListItem/Control[@ControlName='c_FormField1']"/>
</td>
</tr>
<tr>
<td colspan="1" class='heading'>فیلد دوم</td>
<td colspan="3">
<xsl:value-of select="ListItem/Control[@ControlName='c_FormField2']"/>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
3. مقدار دادن به سلولهای خالی
از جاوااسکریپت برای قرار دادن یه عبارت به جای فیلدهایی که توی فرم پُر نشدهن استفاده میکنیم؛ این کد چک میکنه که محتوای تگ td
در html
خالی هست یا نه و اگه خالی بود، عبارت «ثبت نشده» رو اون جا نمایش میده و کلس dataNotEntered
را به td
اضافه میکنه؛ بعداً برای تغییر نمایش فیلدهای خالی، میتونیم از این کلس استفاده کنیم:
const tdElements = document.querySelectorAll("table td")
tdElements.forEach(function(td) {
if (!td.innerHTML.trim()) {
td.innerHTML = "ثبت نشده"
td.classList.add('dataNotEntered')
}
})
4. ایجاد تغییرات در ظاهر فرم
با استفاده از تگ style
در فایل XSLT میتونید مثل هر فایل HTML دیگهای، با استفاده از CSS، استایلهای اختصاصی برای جدول و فونت و اندازهها و خلاصه هر چیز دیگهای اضافه کنید:
<style>
table {
direction: rtl;
width: 100%;
padding: 1em;
}
td {
direction: rtl;
text-align: right;
font-family: b mitra;
border: 1px solid;
padding: .25em;
min-width: 25%;
width: 25%;
}
td:not(.heading) {
font-weight: bold;
}
.heading {
width: 20%;
background: #e3efff;
border: 1px solid #6eacff;
}
.title {
text-align: center;
border: none;
padding-top: 1em;
}
.dataNotEntered {
color: #5b5b5b;
border: 1px dashed;
font-weight: 100 !important;
}
</style>
با اضافه کردن این استایلها میتونید نمای چاپی رو دقیقاً مطابق با نیاز خودتون و سازمانتون تنظیم کنید و به راحتی از طریق کد XSLT، نمای پرینت فرم رو بهصورت حرفهای نمایش بدید.
5. افزودن دکمه چاپ در نمای پرینت
خب، حالا فرم آماده شده. الان میتونیم با جاوااسکریپت یه دکمه برای چاپ به فرم اضافه کنیم تا هر کاربری بتون به راحتی وارد پنجره پرینت بشه و فرم رو به صورت مستقیم چاپ کنه. میتونید هر جایی از قالب HTML موجود توی فایل XSLT از این دکمه استفاده کنید:
<button onclick="window.print();" class="print">چاپ</button>
اما بعد از کلیک کردن روی این دکمه، توی پنجرهای که برای چاپ فرم ظاهر میشه، این دکمه لازم نیست که دیده بشه؛ برای همین باید از استایل زیر توی تگ style
استفاده کنیم تا موقع چاپ، دکمه مخفی بشه:
@media print {
.print{
display:none;
}
}
تموم شد! با دنبال کردن این مراحل، میتونید یه نمای چاپی زیبا و حرفهای برای فرمهای پاورفرمی شیرپوینت بسازید. قالببندی نهایی کدتون توی فایل XSLT باید این شکلی باشه:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<style>
table {
direction: rtl;
width: 100%;
padding: 1em;
}
td {
direction: rtl;
text-align: right;
font-family: b mitra;
border: 1px solid;
padding: .25em;
min-width: 25%;
width: 25%;
}
td:not(.heading) {
font-weight: bold;
}
.heading{
width: 20%;
background: #e3efff;
border: 1px solid #6eacff;
}
.title {
text-align: center;
border: none;
padding-top: 1em;
}
.dataNotEntered {
color: #5b5b5b;
border: 1px dashed;
font-weight: 100 !important;
}
.print {
font-family: b mitra;
border: none;
color: white;
font-weight: bolder;
padding-left: 1em;
padding-right: 1em;
border-radius: 3em;
cursor: pointer;
background: linear-gradient(90deg, #093e71, #0c95ae, #6ec9ca);
}
@media print {
.print{
display:none;
}
}
</style>
<table style="border: 2px das">
<tr>
<td colspan="1" class='heading'>فیلد اول</td>
<td colspan="3">
<xsl:value-of select="ListItem/Control[@ControlName='c_FormField1']"/>
</td>
</tr>
<tr>
<td colspan="1" class='heading'>فیلد دوم</td>
<td colspan="3">
<xsl:value-of select="ListItem/Control[@ControlName='c_FormField2']"/>
</td>
</tr>
</table>
<script>
const tdElements = document.querySelectorAll("table td")
tdElements.forEach(function(td) {
if (!td.innerHTML.trim()) {
td.innerHTML = "ثبت نشده"
td.classList.add('dataNotEntered')
}
})
</script>
</xsl:template>
</xsl:stylesheet>